嗨伙计们,我正在尝试在javascript中创建一个函数,从范围(开始,结束)返回一个数组,并且我应该创建一个可选参数,当它未定义时默认为1.当我提供所有参数时,我可以使函数工作,但当我只传递两个参数时返回一个空数组.这是一个问题:
编写一个范围函数,它接受两个参数,start和end,并返回一个包含从start到(和包括)end的所有数字的数组.
接下来,编写一个sum函数,它接受一个数字数组并返回这些数字的总和.运行上一个程序,看看它是否确实返回55.
作为奖励分配,修改范围函数以采用可选的第三个参数,该参数指示用于构建阵列的"步长"值.如果没有给出步骤,则数组元素以1的增量上升,对应于旧行为.函数调用范围(1,10,2)应返回[1,3,5,7,9].确保它也适用于负步长值,以便范围(5,2,-1)产生[5,4,3,2].
这是我的代码
function range(start, end, increment){
var array = [];
var current = start;
var counter;
if (increment == undefined){
counter = 1;
}
else {
counter = increment;
}
if (increment > 0){
while(current <= end){
array.push(current);
current += counter;
}
}
else if (increment < 0){
while(current >= end){
array.push(current);
current += counter;
}
}
return array;
}
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么它会破裂?我知道一些c#和我过去能够在视觉工作室跳入调试器时出现问题而不像javascript
您可以稍微简化代码并使用increment变量进行递增.但在此之前,我建议以测试值是falsy( ,,0 等),然后分配给它.nullundefined1
未实现:检查start和end是适当的.
function range(start, end, increment) {
var array = [];
var current = start;
increment = increment || 1;
if (increment > 0) {
while (current <= end) {
array.push(current);
current += increment;
}
} else {
while (current >= end) {
array.push(current);
current += increment;
}
}
return array;
}
console.log(range(1, 3, 0));
console.log(range(2, 5));
console.log(range(1, 9, 1));
console.log(range(5, 2, -1)); Run Code Online (Sandbox Code Playgroud)
一个非常简单的单向(上行),包含的范围-从进入x到y通过增加1各一次。
// range :: (Int, Int) -> [Int]
const range = (x,y) =>
x > y ? [] : [x, ...range(x + 1, y)];
console.log(range(1,4)); // [1,2,3,4]
console.log(range(3,3)); // [3]
console.log(range(6,3)); // []Run Code Online (Sandbox Code Playgroud)
支持双向(升序或降序)范围的轻微适应- 仍然增加或减少1
// range :: (Int, Int) -> [Int]
const range = (x,y) => {
if (x > y)
return range(y,x).reverse();
else
return x === y ? [y] : [x, ...range(x + 1, y)];
}
console.log(range(1,4)); // [1,2,3,4]
console.log(range(3,3)); // [3]
console.log(range(6,3)); // [6,5,4,3]Run Code Online (Sandbox Code Playgroud)
另一种使用高阶函数来更好地控制范围的改编——这有效地为您提供了一些人正在寻找的步进/递增行为——但这更强大,因为它允许您使用函数, t, 来选择下一个值.
const gte = x => y => y >= x;
const lte = x => y => y <= x;
const add = x => y => y + x;
const sub = x => y => y - x;
// range :: (Int, (Int -> Bool), (Int -> Int)) -> [Int]
const range = (x, p, t) => {
if (p(x))
return [x, ...range(t(x), p, t)];
else
return [];
};
console.log(range(2, lte(8), add(2))); // [2,4,6,8]
console.log(range(9, gte(0), sub(3))); // [9,6,3,0]
console.log(range(9, gte(0), sub(5))); // [9, 4]
// very power. wow.
const double = x => x + x;
console.log(range(2, lte(50), double)); // [2,4,8,16,32]Run Code Online (Sandbox Code Playgroud)
此函数具有与forand相同的固有风险while- 由您决定是否将其置于无限循环中。
功能超载
警告:前面是深奥的、不切实际的功能。以下信息仅供您学术愉快。
该range函数也恰好是我最喜欢的Y组合器演示之一。我将在这里向您展示两个示例。
幼稚的 range
const U = f => f (f);
const Y = U (h => f => f (x => h (h) (f) (x)));
const range = Y (f => acc => x => y =>
x > y ? acc : f ([...acc, x]) (x + 1) (y)
) ([]);
console.log(range (3) (6)); // [3,4,5,6]
console.log(range (6) (6)); // [6]
console.log(range (9) (6)); // []Run Code Online (Sandbox Code Playgroud)
和高阶 range
const U = f => f (f);
const Y = U (h => f => f (x => h (h) (f) (x)));
const lt = x => y => y < x;
const gt = x => y => y > x;
const add1 = x => x + 1;
const sub1 = x => x - 1;
const range = Y (f => acc => x => p => t =>
p(x) ? f ([...acc, x]) (t(x)) (p) (t) : acc
) ([]);
console.log(range (3) (lt(6)) (add1)); // [3,4,5]
console.log(range (6) (lt(6)) (add1)); // []
console.log(range (9) (gt(6)) (sub1)); // [9,8,7]Run Code Online (Sandbox Code Playgroud)
那是多么美妙的事情啊。
| 归档时间: |
|
| 查看次数: |
2761 次 |
| 最近记录: |