在javascript中制作范围功能

5 javascript

嗨伙计们,我正在尝试在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

Nin*_*olz 5

您可以稍微简化代码并使用increment变量进行递增.但在此之前,我建议以测试值是falsy( ,,0 等),然后分配给它.nullundefined1

未实现:检查startend是适当的.

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)


Tha*_*you 5

一个非常简单的单向(上行),包含的范围-从进入xy通过增加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)

那是多么美妙的事情啊。