【问题标题】:How to loop through an object (evaluating three properties) and push into an array correctly?如何遍历一个对象(评估三个属性)并正确推入一个数组?
【发布时间】:2019-09-11 08:54:06
【问题描述】:

我需要创建一个名为 runOnRange 的函数。 我有一个包含三个属性的对象:开始、结束和步骤。 根据这些属性,它应该将特定数字推送到(新)数组。一旦完成,应该返回数组。

它是初学者,所以没有花哨的技术,只有循环和条件。

示例 - 我认为它们最能说明需要什么:

runOnRange({start: 10, end: 17, step: 3})

// => 10 // => 13 // => 16

runOnRange({start: -6, end: -4})

// => -6 // => -5 // => -4

runOnRange({start: 12, end: 12})

// 在这种情况下不应该记录任何内容!

runOnRange({start: 23, end: 26, step: -1})

// 在这种情况下不应该记录任何内容!

runOnRange({start: 26, end: 24, step: -1})

// => 26 // => 25 // => 24

runOnRange({start: 23, end: 26, step: 0})

// 在这种情况下不应该记录任何内容!

这是我目前的代码:

function runOnRange (object) {
    var arrNew = []
    var start = object.start
    var end = object.end
    var step = object.step

    //Case 1: steps betwenn start and end range
    if(start + step <= end && start + step >= start) {
        for (var i = start; i <= end; i = i + step) {
            arrNew[i]=i;
        }
    }

    //Case 2: steps not set in which case increments in one
    if (step == undefined) {
        step == 1;
        if(start + step <= end && start + step >= start) {
            for (var i = start; i <= end; i = i + step) {
                arrNew[i]=i
            }
        }
    }
    return arrNew
}

运行实例

runOnRange({start: 10, end: 17, step: 3})

会导致

(17) [empty × 10, 10, empty × 2, 13, empty × 2, 16] 

在控制台中,所以至少有一个错误。

跑步

runOnRange({start: -6, end: -4})

导致一个空数组,即使它应该将 steps 参数设置为 1 并增加。

我在哪里搞砸了?

【问题讨论】:

  • // =&gt; -26 // =&gt; -25 // =&gt; -24 为什么会有这个结果?起始数为正数,终点可达。
  • @NinaScholz 抱歉,错字,已编辑
  • 您的案例 2 中有错字。“step == 1”应该是“step = 1”

标签: javascript arrays loops object


【解决方案1】:

为了不创建稀疏数组,您只需要将arrNew[i] 中的i 增加一个一个,而不是逐步增加 - 但使用push 会更容易.

更简单的是,我只是一个普通的while 循环,其中函数采用默认为 1 的可选 step 参数:

function runOnRange ({ start, end, step = 1 }) {
  const arr = [];
  if (step === 0) { // an odd exception...
    return arr;
  }
  let currNum = start;
  while (start < end ? (currNum < end) : (currNum > end)) {
    arr.push(currNum);
    currNum += step;
  }
  return arr;
}

console.log(runOnRange({start: 10, end: 17, step: 3}));
console.log(runOnRange({start: 12, end: 12}));
console.log(runOnRange({start: 26, end: 24, step: -1}));

【讨论】:

  • 查看代码:const 和 let 还不是我的技能。此时只有 var
  • 使用 varconstlet 在这里没有区别,如果你愿意,可以随意用 var 替换它们(不过,constlet 应该是编写代码时更可取,它们的陷阱更少)
  • @user2132380 对象解构会让你大吃一惊:) 不确定这个答案是否会遗漏这种情况下可能出现无限循环的细微差别:runOnRange({start: 23, end: 26, step: -1})(注意:我检查过 - 它确实是!)
  • 它似乎不适用于 runOnRange({start: 20, end: 26, step: 3}) 应该是 [ 20, 23, 26 ] 和 runOnRange({start: 26, end: 24, step: -1}) 这应该是 [ 26, 25, 24 ]
  • 如果 constlet 超出 OP 范围,则只是提示,那么 option object patternobject destructuring 可能更超出范围。
【解决方案2】:

唷,这实际上有点冗长,以涵盖您的所有情况。但最重要的部分是

  • 使用array.push 代替索引
  • 无需重复,如果 step 未定义,只需将其设置为 1 即可
  • 如果step 为零,则提前返回
  • 如果step 为>0 或

function runOnRange(obj){
   var start = obj.start;
   var end = obj.end;
   var step = (obj.step == undefined) ? 1 : obj.step;
   var arrNew = [];
   if(step == 0) return arrNew;
   
   if((step>0 && start + step <= end && start + step >= start) || (step<0 && start + step >= end && start + step <= start)) {
        for (var i = start; (step>0 && i <= end) || (step<0 && i>=end); i = i + step) {
            arrNew.push(i);
        }
    }
    return arrNew;
}

console.log(runOnRange({start: 10, end: 17, step: 3}))
// => 10 // => 13 // => 16

console.log(runOnRange({start: -6, end: -4}))
// => -6 // => -5 // => -4

console.log(runOnRange({start: 12, end: 12}))
// nothing should be console.logged in this case!

console.log(runOnRange({start: 23, end: 26, step: -1}))
// nothing should be console.logged in this case!

console.log(runOnRange({start: 26, end: 24, step: -1}))
// => 26 // => 25 // => 24

console.log(runOnRange({start: 23, end: 26, step: 0}))
// nothing should be console.logged in this case!

【讨论】:

  • 需要查看这个@Jamiec 就像你的一些组合一样 - 不知道可以以这种方式组合事物。我唯一不明白的是: var step = obj.step == undefined ? 1:obj.step;逐字逐句是什么意思?
  • 它是ternary operator,是var result = booleanCondition ? resultIfTrue : resultIfFalse的缩写
  • @user2132380 我添加了括号,以便更容易阅读布尔条件的位置
  • 哇,好神奇的技术
【解决方案3】:

好的,

我想,这段代码可以解决问题。它当然不漂亮,也许是多余的,但在这一点上,这是我能想到的。

function runOnRange (object) {
    var arrNew = []
    var start = object.start
    var end = object.end
    var step = object.step

    //Case 0: handle 0 for step
    if (step === 0) {
        return arrNew
    }

    //Case 1a: steps between start and end range, start smaller then end
    if(start + step <= end && start + step >= start) {
        for (var i = start; i <= end; i = i + step) {
            arrNew.push(i)
        }
    }

    //Case 1b: steps between start and end range, start higher then end
    if(start + step >= end && start + step <= start) {
        for (var i = start; i >= end; i = i + step) {
            arrNew.push(i)
        }
    }

    //Case 2: steps not set in which case increments in one
    if (step == undefined) {
        step == 1;
        if(start + step <= end && start + step >= start) {
            for (var i = start; i <= end; i = i + step) {
                arrNew[i]=i
            }
        }
    }
    return arrNew
}

【讨论】:

  • 你现在会有一个无限循环。它不在您的任何测试用例中,但仍然存在。检查你的答案。
  • @Jamiec thx 指出:你能给我一个我会遇到这样一个循环的例子吗?更重要的是:我需要改变什么来避免它?
  • 我的错,我没看到你也走了另一条路(拆分 1a 和 1b)。干得好,你有一个解决方案!如果您想要一个 更短的 解决方案,我的答案可能对您有用 :) 我做的完全一样,但都在一个循环中。
猜你喜欢
  • 2018-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-19
  • 2022-12-11
  • 1970-01-01
  • 2014-12-21
相关资源
最近更新 更多