原始数组已更改,未做任何修改

时间:2018-09-04 10:22:11

标签: javascript arrays

我正在尝试从数组中删除重复的对象,并仅保留具有最高nb值的对象。

示例:

从此数组:

let arr = [
      {id: 1, nb: 1},
      {id: 1, nb: 4},
      {id: 2, nb: 1},
      {id: 3, nb: 1},
      {id: 1, nb: 2},
      {id: 1, nb: 3},
      {id: 2, nb: 7},
      {id: 2, nb: 8},
    ];

我应该得到这个:

arr2 = [
   { id: 1, nb: 4 },
   { id: 2, nb: 8 }, 
   { id: 3, nb: 1 }
]

以下算法在理论上是非常正确的,但是我看到原始数组在最后被修改了(请参见下面的最后一个console.log(arr)

代码:

let arr = [
  {id: 1, nb: 1},
  {id: 1, nb: 4},
  {id: 2, nb: 1},
  {id: 3, nb: 1},
  {id: 1, nb: 2},
  {id: 1, nb: 3},
  {id: 2, nb: 7},
  {id: 2, nb: 8},
];
// Original array
console.log(arr);

let tmp = {};
for(let i=0; i<arr.length; i++) {
  if( !tmp[arr[i].id] ) {
    tmp[arr[i].id] = arr[i];     
  } else {
    if (tmp[arr[i].id].nb < arr[i].nb ) {
      tmp[arr[i].id].nb = arr[i].nb;
    }
  }     
}

var result = Object.values(tmp);
// This output the desired result
console.log(result);
// Why the original array changed ?
console.log(arr);

这将输出:

> Array [Object { id: 1, nb: 1 }, Object { id: 1, nb: 4 }, Object { id: 2, nb: 1 }, Object { id: 3, nb: 1 }, Object { id: 1, nb: 2 }, Object { id: 1, nb: 3 }, Object { id: 2, nb: 7 }, Object { id: 2, nb: 8 }]
> Array [Object { id: 1, nb: 4 }, Object { id: 2, nb: 8 }, Object { id: 3, nb: 1 }]
> Array [Object { id: 1, nb: 4 }, Object { id: 1, nb: 4 }, Object { id: 2, nb: 8 }, Object { id: 3, nb: 1 }, Object { id: 1, nb: 2 }, Object { id: 1, nb: 3 }, Object { id: 2, nb: 7 }, Object { id: 2, nb: 8 }]

为什么除了循环之外没有其他处理时,原始数组会发生变化?

2 个答案:

答案 0 :(得分:2)

tmp映射中的对象和arr共享相同的对象引用时,原始数组最后更新。因此,在tmp中所做的更改将反映在arr中。您可以使用Object.assign()使其指向单独的参考。请尝试以下操作:

let arr = [ {id: 1, nb: 1}, {id: 1, nb: 4}, {id: 2, nb: 1}, {id: 3, nb: 1}, {id: 1, nb: 2}, {id: 1, nb: 3}, {id: 2, nb: 7}, {id: 2, nb: 8}, ];


let tmp = {};
for(let i=0; i<arr.length; i++) {
  if( !tmp[arr[i].id] ) {
    tmp[arr[i].id] = Object.assign({},arr[i]);     
  } else {
    if (tmp[arr[i].id].nb < arr[i].nb ) {
      tmp[arr[i].id].nb = arr[i].nb;
    }
  }     
}

var result = Object.values(tmp);
console.log(result)

答案 1 :(得分:1)

因为两个数组中的对象共享相同的引用。

您将需要更新

tmp[arr[i].id] = arr[i];

tmp[arr[i].id] = JSON.parse(JSON.stringify(arr[i]));

let arr = [
  {id: 1, nb: 1},
  {id: 1, nb: 4},
  {id: 2, nb: 1},
  {id: 3, nb: 1},
  {id: 1, nb: 2},
  {id: 1, nb: 3},
  {id: 2, nb: 7},
  {id: 2, nb: 8},
];

let tmp = {};
for(let i=0; i<arr.length; i++) {
  if( !tmp[arr[i].id] ) {
    tmp[arr[i].id] = JSON.parse(JSON.stringify(arr[i]));     
  } else {
    if (tmp[arr[i].id].nb < arr[i].nb ) {
      tmp[arr[i].id].nb = arr[i].nb;
    }
  }     
}

var result = Object.values(tmp);
console.log(arr); // original array unchanged