【问题标题】:Javascript spread on array index to 'push' new item to nested arrayJavascript 在数组索引上传播以“将”新项目“推送”到嵌套数组
【发布时间】:2023-01-20 00:20:35
【问题描述】:

考虑以下数据:

let data = [
    { foo: true, bar: [ 1, 2, 3 ] },
    { foo: true, bar: [ 8, 9,   ] }
];

我正在尝试使用 spread syntax (...) 将 push 的内容添加到索引 1 上的嵌套 bar 数组。

所以最终的数组应该变成:

[
    { foo: true, bar: [ 1, 2, 3 ] },
    { foo: true, bar: [ 8, 9, 'new-item'  ] }
]

一般情况下,我们直接push:data[1].bar.push(0),但是我需要一个传播方案


我试过使用这种方法:
How to push new elements to a nested array of objects in JavaScript using spread syntax

data = [ ...data, {[1]: { ...data[1], bar: [ ...data[1].bar, 'new-item' ] } }] 

但这将附加另一个具有单个键1的对象,它不会改变data[1]


然后,我尝试使用Object.assign(),但又得到了一个新索引:
Replace array entry with spread syntax in one line of code?

data = [ ...data, Object.assign({}, data[1], { bar }})

tl;博士,我如何将一些东西附加到一个数组,一个对象的一部分,它位于一个对象数组中,使用传播语法

请将我链接到副本,或提供一种方法来执行此操作


操场:

let data = [
    { foo: true, bar: [ 1, 2, 3 ] },
    { foo: true, bar: [ 8, 9 ] }
];

// 'Regular' push method
// data[1].bar.push(0);

// Using spread reassign
// data = [ ...data, {[1]: { ...data[1], bar: [ ...data[1].bar, 'new-item' ] } }] 

// Using Object.assign
data = [ ...data, Object.assign({}, data[1], {bar: [ 'new-item' ] } ) ];

console.log(data)

【问题讨论】:

  • 我没有发布答案,但这似乎有效:data = [ data[0], { ...data[1], bar: [ ...data[1].bar, 'new-item' ] } ]

标签: javascript arrays spread


【解决方案1】:

您可以采用一个外部 Object.assign,其中一个数组作为目标,一个以索引作为键的对象。

let
    data = [
        { foo: true, bar: [1, 2, 3] },
        { foo: true, bar: [8, 9] }
    ];

data = Object.assign(
    [...data],                            // target array
    { 1: {                                // array index as key
        ...data[1],
        bar: [...data[1].bar, 'new-item']
    } }
);

console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    【解决方案2】:

    您可以在数组本身上使用 Object.assign

    let data = [
        { foo: true, bar: [ 1, 2, 3 ] },
        { foo: true, bar: [ 8, 9,   ] }
    ];
    data = Object.assign([...data], {1: { ...data[1], bar: [...data[1].bar, 'new-item']}});
    console.log(data);

    【讨论】:

      【解决方案3】:

      我不认为这比向您开放的许多其他选项更具可读性,但这满足了“使用对象传播”的要求。

      let data = [
        { foo: true, bar: [ 1, 2, 3 ] },
        { foo: true, bar: [ 8, 9,   ] },
        { foo: false, bar: [ ] }
      ];
      
      let idx = 1;
      let newData = [ 
        ...data.slice(0, idx), 
        { 
          ...data[idx], 
          bar: [ ...data[idx].bar, 'new-item' ]
        },
        ...data.slice(idx+1)
      ];
      
      console.log(newData);

      这将首先获取您的数据并将数组剪切到您要替换的项目(索引 1)。接下来是一个新对象,然后是数组的其余部分(如果有的话)。

      【讨论】:

        【解决方案4】:

        没有什么比像这样覆盖结果数组中的项目更好的了:

        let data = [
            { foo: true, bar: [ 1, 2, 3 ] },
            { foo: true, bar: [ 8, 9, ] }
        ];
        
        let result = [...data];
        //overwriting the [1] element with a new object based on the previous one + one item in .bar array
        result[1] = {...result[1], bar: [...result[1].bar, 'new-item']};
        
        console.log(result)

        【讨论】:

          【解决方案5】:

          您要重写 data 数组吗? 如果不是,这里有一个使用扩展运算符的简单解决方案:

          let data = [
              { foo: true, bar: [ 1, 2, 3 ] },
              { foo: true, bar: [ 8, 9,   ] }
          ];
          
          data[1].bar = [...data[1].bar, 'new-item'];
          
          console.log(data);
          
          // data = [
          //  { foo: true, bar: [1, 2, 3] },
          //  { foo: true, bar: [8, 9, 'new-item'] }
          // ];

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-05-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多