【问题标题】:Looping over an array, and pushing data to another array循环数组,并将数据推送到另一个数组
【发布时间】:2017-06-22 04:59:10
【问题描述】:

我正在用 JavaScript 编写一个小脚本来输出一个数组。 我想使用 'years' 数组,将数据推送到另一个名为 new_array 的数组中,并通过 console.log() 输出

唯一的问题是,这是输出!

years = [1996, 1994, 1981, 1976];
new_array = [];


for(i = 0; i <= years.length; i++) {
    popped_element = Object.values(years.pop([i]));
    new_array.push(popped_element);
    console.log(new_array)

}

【问题讨论】:

  • 未定义是由于
  • 你为什么使用Object.values
  • 你想达到什么目的?
  • 你真的只是想Array.reverse()吗?那已经存在了。 years.pop([i])?那应该做什么? Object.values() 将 Object 作为参数。
  • Array.prototype.pop 不接受任何参数,它们被忽略。它总是返回数组的最后一个元素。

标签: javascript


【解决方案1】:

删除循环内第一行对 Object.values() 的调用以解决空数组问题:

popped_element = years.pop();

来自MDN:

Object.values() 方法返回给定对象自己的可枚举属性值的数组。

您的年份没有可枚举的属性值,因此它返回一个空数组并将该空数组作为一个元素添加到 new_array 中。

末尾的undefined 是由于&lt;= years.length 中的=。要修复,请制作该循环线:

for(i = 0; i < years.length; i++) {

或者更好的是,在循环之前存储长度并与之进行比较,而不是在每次循环迭代时访问 years.length,因为 pop() 会更改数组长度。

【讨论】:

  • 如果您在从头开始迭代时使用 years.pop(),您的循环将在中间结束。你的结果将是 years = [1996, 1994]; new_array=[1976, 1981]`;
  • "你的年份没有可枚举的属性值" 是的。问题是 OP 在 years.pop() 上调用 Object.values,所以实际上是 Object.values('1976')
  • @RobG 与复数 years相比,单数 set 年份的英文似乎缺少一个关键区别,它具有属性> 他们自己(例如'1976')没有。我的观点与您想说的相同,但您误解了这一点。
  • @wbt——我当然可以做出这种区分,但它是在你的脑海中,而不是在散文中。 ;-)
  • @RobG 看看我的散文和复数动词“have”的使用,指的是数组的元素。查看您引用该内容的评论以及您尝试使用单数形式“it”和“does”来反驳它,显然是指数组本身。看到不匹配了吗? (我下一句中的“It”指的是函数,Object.values。)
【解决方案2】:

你没有说代码的意图是什么,但它还是有一些问题:

for(i = 0; i <= years.length; i++) {
    popped_element = Object.values(years.pop([i]));

Object.values 是实验性的,不能广泛使用,所以你不应该使用它。 pop 不接受任何参数,因此您每次popyears 的最后一个值。您正在对 pop 返回的值调用 Object.values,这是一个没有任何可枚举属性的字符串,因此是空数组。

如果您打算以相反的顺序返回数组的副本,则复制该数组并将其反转:

var years = [1996, 1994, 1981, 1976];

// Copy with slice, reverse with reverse
var reversed = years.slice().reverse();
console.log(reversed)

【讨论】:

    【解决方案3】:

    你已经把它复杂化了,你不要同时使用 for 循环和 pop 除非你从头到尾迭代

    如果你从头开始迭代,同时弹出结尾,你只会得到一半的数组:

     years = [1996, 1994, 1981, 1976];
            new_array = [];
    
    
            for(i = 0; i < years.length; i++) {
              new_array.push(years.pop());
    
            }
              console.log(new_array)

    如果要修改原始数组,您有两种选择

    1) 使用 While 循环

    只要原始数组中还有元素,就一直循环

    years = [1996, 1994, 1981, 1976];
        new_array = [];
        
        
    while(years.length) {
      new_array.push(years.pop());
    
    }
    
      console.log(new_array)

    2) 使用递减的 For 循环

    从循环的末尾迭代到开头

    years = [1996, 1994, 1981, 1976];
    new_array = [];
    
    
    for(i = years.length - 1; i >= 0; i--) {
      new_array.push(years.pop());
    
    }
      console.log(new_array)

    【讨论】:

    • 在第一个 sn-p 中颠倒 i 上的计数顺序并不会改变代码的工作方式,但会使其不那么标准,与原始代码不同,并且更有可能成为代码的来源未来的一个错误。
    • 它绝不会增加错误的可能性,并且反向循环不违反标准。如果你从最后弹出,你不会修改你正在唤醒的数组,同时以递增的顺序循环它。否则你会在第二次迭代中结束
    • 如果您计算从 0 到 length 的迭代次数,并从末尾到开头删除项目,那么您的开始项目将永远不会是 poped
    • 进入循环前只需保存长度即可。 for(var len = array.length; len; len--)!
    • 公平的,忘了我们在弹出,但如果你要这样做,只需使用 while 循环
    【解决方案4】:

    也许你真的想这样做?

    var years = [1996, 1994, 1981, 1976];
    var reverse_years = years.slice().reverse(); // years.slice() creates new instance of Array so .reverse() does not affect original Array
    console.log(reverse_years);
    

    如果您不在乎原始数组是否受到影响:

    var years = [1996, 1994, 1981, 1976];
    years.reverse(); console.log(years);
    

    【讨论】:

    • 他之后不需要原始数组(因为那些.pop调用它会是空的)。那么为什么要使用.slice。把它倒过来!
    • 当然,如果您不再使用几年,您可以简单地执行years.reverse();,甚至无需将其分配给任何东西,因为原始数组会受到影响。
    【解决方案5】:

    只需迭代和赋值:

    years = [1996, 1994, 1981, 1976];
    new_array = [];
    
    
    for(var i=0; i<years.length; i++) {
        new_array.push(years[i]);
        console.log(new_array);
    }
    

    然后以崇高的顺序排列元素(如果这是您想要的):

    new_array.reverse();
    

    并删除多年的项目(再次,如果这是您想要的):

    years = [];
    

    ..或者,只需使用slice 复制:

    new_array = years.slice();
    

    【讨论】:

    • 这比 OP 的策略占用更多的内存 [一旦更正了实现]。
    • @WBT 我认为您可能误以为Array.pop() 会减少阵列使用的内存。它可能会,但可能不会。数组访问也比数组变异快得多......
    • 如果您只是获取所有元素,这实际上是最有效的解决方案
    • 虽然不是从头开始循环然后反转,而是从末尾迭代并重新分配旧数组。
    • @TheRealMrCrowley——我同意你的观点,但是在最近的浏览器中,数组方法比以前快得多,以至于现在与 for 没有显着的性能差异或其他类型的循环。甚至DOM NodeLists 也获得了 forEach (iterable&lt;Node&gt;;)。 ;-)
    猜你喜欢
    • 2021-06-01
    • 2018-07-11
    • 2018-06-26
    • 1970-01-01
    • 1970-01-01
    • 2014-02-04
    • 2019-01-28
    • 1970-01-01
    • 2017-03-02
    相关资源
    最近更新 更多