【问题标题】:Updating object properties and adding them in a new Arr with Reduce Javascript使用 Reduce Javascript 更新对象属性并将它们添加到新的 Arr
【发布时间】:2018-05-28 19:55:20
【问题描述】:

我试图在具有键值对属性的对象数组上使用 addKeyAndValue 函数中的 reduce,在每个对象中添加一个新的键值对并将其返回到一个新数组中。 addKeyAndValue 函数接收三个参数,即 arr、键和要在数组中每个对象中相加的值。然后,我在 Reduce 回调中使用 push 将数组中的对象推送到累加器中的新数组,并使用括号表示法使用更新的新键和值。

var arr = [{name: 'Alonso'}, {name: 'James'}, {name: 'Chris'}, {name: 'Steve'}]

function addKeyAndValue(arr, key, value){
    return arr.reduce(function(acc, nextValue, idx){
        console.log(next);
        acc.push(nextValue[key] = value);
        return acc;
    },[]);
}

预期的结果应该是:

addKeyAndValue(arr, 'title', 'Instructor') // 
      [
        {title: 'Instructor', name: 'Alonso'}, 
        {title: 'Instructor', name: 'James'}, 
        {title: 'Instructor', name: 'Chris'}, 
        {title: 'Instructor', name: 'Steve'}
       ]

但是,我在 Chrome 开发控制台中得到的结果是:

(4) ["Instructor", "Instructor", "Instructor", "Instructor"]
0:"Instructor"
1:"Instructor"
2:"Instructor"
3:"Instructor"
length:4
__proto__:Array(0)

我想知道为什么通过nextValue[key] 传递的值会覆盖整个对象并仅作为字符串返回。当我尝试仅将现有对象推送到新数组中时,它可以正常工作,但是当推送nextValue[key] 时,它会变为未定义,并且在执行上述nextValue[key] = value 时,它会将对象覆盖到仅包含instructor 字符串的新数组中。我有点困惑,因为我期待不同的结果。

在 nextValue 上使用方括号符号 nextValue[key],这是数组中的每个对象都被 reduce 方法中的回调迭代,我认为在这种情况下会添加一个新的键属性 "title",分配值为 @987654330 @。

任何帮助将不胜感激,谢谢:)。

【问题讨论】:

    标签: javascript arrays javascript-objects reduce square-bracket


    【解决方案1】:

    您正在将赋值结果推送到数组中,而不是对象中。

    因为结果nextValue[key] = valuevalue。使用acc.push(nextValue[key] = value); 就像使用acc.push(value)

    由于您要更新每个对象,use Array#map 来迭代数组。使用Object#assign 克隆每个对象(以防止改变原始对象),并添加属性:

    var arr = [{name: 'Alonso'}, {name: 'James'}, {name: 'Chris'}, {name: 'Steve'}];
    
    function addKeyAndValue(arr, key, value){
      return arr.map(function(obj){
        var clone = Object.assign({}, obj);
        clone[key] = value;
        return clone;
      });
    }
    
    var result = addKeyAndValue(arr, 'title', 'Instructor');
    
    console.log(result);

    ES6 版本

    const arr = [{name: 'Alonso'}, {name: 'James'}, {name: 'Chris'}, {name: 'Steve'}];
    
    function addKeyAndValue(arr, key, value){
      return arr.map((obj) => Object.assign({ [key]: value }, obj));
    }
    
    const result = addKeyAndValue(arr, 'title', 'Instructor');
    
    console.log(result);

    【讨论】:

    • 感谢您的回答,但我很了解其他数组方法,并且我确实使用 reduce 以另一种方式解决了这个问题,但我尚不清楚为什么我在这里分享的方法不起作用。我想不通。
    • 看第一句话。我将添加一个示例。
    • 是的,我明白了,但仍然不知道为什么会这样。如果您在上面查看 tricont 共享的代码与我的完全相同,但他只是将 nextValue[key] = value 放在单独的行中,然后放在 acc.push(nextValue) 下方,这可以按我的意愿工作。然而,在那种情况下,它并没有覆盖将它添加到对象而不是数组中的对象。
    • 你在改变原来的对象nextValue[key] = value,但是你推送的不是对象,而是赋值的结果。结果是value。对象已更改,但未推送到新数组中。如果您console.log(arr),您会看到原始对象已更改。在 trincots 的回答中,他将值分配给对象,然后推送对象。
    • 是的,我确实注意到前一段时间在我的控制台中通过在 arr 上使用 console.log。另一方面,我第一次看到 trincot 使用带两个括号的方法,他用括号包裹了 nextValue[key] = value, nextValue 并且它确实工作正常。但我想知道背后的原因,因为我不想再跳类似的问题。
    【解决方案2】:

    您的push 参数只会导致value 被推送,而不是对象。如果你真的想在一个表达式中解决这个问题,你可以使用逗号运算符来解决这个问题:

    acc.push((nextValue[key] = value, nextValue));
    

    但是如果你单独做它可能会更易读:

    nextValue[key] = value;
    acc.push(nextValue);
    

    【讨论】:

    • 您所做的第一行没有产生预期的结果,因为它将指导员与更新的对象一起打印,但第二行完成了这项工作。但仍然想知道为什么您共享的第二行单独工作,然后 acc.push(nextValue[key] = value);因为对我来说基本上是一样的。
    • 你注意到多余的括号了吗?我在发布后几秒钟添加了它们?
    • 您的版本不起作用,因为您没有推送对象。该分配只给你分配的值,而不是变异的对象。
    • 我看到@trincot 在 js 中似乎很奇怪的行为,您分享的第一行是正确的,需要将 nextValue[key] = value, nextValue 放在它自己的括号内。知道为什么需要这样做吗?这是我第一次看到它被这样使用。
    • 内括号使逗号充当运算符而不是函数参数分隔符。搜索逗号运算符。
    猜你喜欢
    • 2021-10-10
    • 1970-01-01
    • 2011-02-16
    • 1970-01-01
    • 2016-12-19
    • 2012-03-16
    • 2016-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多