从对象数组中删除相同的值

时间:2020-03-16 14:47:06

标签: javascript arrays json loops javascript-objects

我想通过比较2个数组从数组中删除同一对象。

样本数据:

import requests

URL = 'https://github.com/XYZ/file.zip'
r = requests.get(url)
# open method to open a file on your system and write the contents    
with open("file.zip", "wb") as code:
    code.write(r.content)

8 个答案:

答案 0 :(得分:6)

Array.filter而不是Array.some

这里的诀窍还在于不要some,..

const arr1 = [
  {id: 1, name: "a"},
  {id: 2, name: "b"},
  {id: 3, name: "c"},
  {id: 4, name: "d"},
], arr2 = [
  {id: 1, name: "a"},
  {id: 4, name: "d"},
];

const newArray=arr1.filter(a=>!arr2.some(s=>s.id===a.id));

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

正如评论中提到的那样,对该问题的解释可能略有不同。如果您还想要arr2中的取消项目,则基本上只需执行两次并加入。 IOW:检查arr1中arr2中没有的内容,然后检查arr2中arr1中没有的内容。

例如。

const notIn=(a,b)=>a.filter(f=>!b.some(s=>f.id===s.id));
const newArray=[...notIn(arr1, arr2), ...notIn(arr2, arr1)];

更新2: 如qiAlex所述,时间复杂度在循环内存在循环。尽管some会在找到匹配项时发生短路,但如果数据集变大,事情可能会变慢。这是SetMap进来的。

因此,请使用Set来解决此问题。

const notIn=(a,b)=>a.filter(a=>!b.has(a.id));
const newArray=[
  ...notIn(arr1, new Set(arr2.map(m=>m.id))),
  ...notIn(arr2, new Set(arr1.map(m=>m.id)))
];

答案 1 :(得分:2)

const isInArray = (arr, id, name) => arr.reduce((result, curr) => ((curr.name === name && curr.id === id) || result), false)

const newArray = arr1.reduce((result, curr) => (isInArray(arr2, curr.id, curr.name) ? result : result.concat(curr)), [])

答案 2 :(得分:1)

您可以使用filter()方法来更新代码,而不是使用.map()方法,例如:

const arr1 = [
  {id: 1, name: "a"},
  {id: 2, name: "b"},
  {id: 3, name: "c"},
  {id: 4, name: "d"},
], arr2 = [
  {id: 1, name: "a"},
  {id: 4, name: "d"},
];

let newArray = []; // new array with with no same values it should be unique.
newArray = arr1.filter(function(a) {
    for(var i=0; i < arr2.length; i++){
      if(a.id == arr2[i].id) return false;
    }
    return true;
});
console.log(newArray);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 3 :(得分:1)

您可以使用Array.prototype.some检查第一个数组中的每个元素的id是否位于第二个数组中。如果不存在该元素,则仅产生它。

const arr1 = [
  {id: 1, name: "a"},
  {id: 2, name: "b"},
  {id: 3, name: "c"},
  {id: 4, name: "d"},
];

const arr2 = [
  {id: 1, name: "a"},
  {id: 4, name: "d"},
];

const result = arr1.filter(x => !arr2.some(y => y.id === x.id));

console.log(result);

答案 4 :(得分:1)

我认为一个简单的比较器可以获取差异,然后加以衔接。 使用这种方法,您无需检查哪个数组更大。

arr1 = [  {id: 1, name: "a"},  {id: 2, name: "b"},  {id: 3, name: "c"},  {id: 4, name: "d"}];

arr2 = [  {id: 1, name: "a"},  {id: 4, name: "d"},];

function localComparer(b){
  return function(a){
    return b.filter(
    function(item){
      return item.id == a.id && item.name == a.name
    }).length == 0;
  }
}

var onlyInArr1 = arr1.filter(localComparer(arr2));
var onlyInArr2 = arr2.filter(localComparer(arr1));

console.log(onlyInArr1.concat(onlyInArr2));

答案 5 :(得分:1)

我们可以通过检查当前数组中是否不包含some元素来过滤值:

const result = arr1.reduce((a, c) => {
  if (!arr2.some(a2 => a2.id === c.id))
      a.push(c);
  return a;
}, [])

一个例子:

let arr1 = [
  {id: 1, name: "a"},
  {id: 2, name: "b"},
  {id: 3, name: "c"},
  {id: 4, name: "d"},
];

let arr2 = [
  {id: 1, name: "a"},
  {id: 4, name: "d"},
];

const result = arr1.reduce((a, c) => {
  if (!arr2.some(a2 => a2.id === c.id))
      a.push(c);
  return a;
}, [])

console.log(result);

答案 6 :(得分:1)

尝试这个-

const arr1 = [
  {id: 1, name: "a"},
  {id: 2, name: "b"},
  {id: 3, name: "c"},
  {id: 4, name: "d"},
];

const arr2 = [
  {id: 1, name: "a"},
  {id: 4, name: "d"},
];

const arr3 = [...arr1, ...arr2];
const mySubArray = _.uniq(arr3, 'id');
console.log(mySubArray);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>

答案 7 :(得分:1)

每个答案中有那么多循环。

我的答案的代码复杂度是2N,

想法是:

  1. 合并数组。

  2. 第一个循环-以某种方式标记重复项

  3. 第二个循环-过滤出重复项

arr1 = [
  {id: 1, name: "a"},
  {id: 2, name: "b"},
  {id: 3, name: "c"},
  {id: 4, name: "d"},
];

arr2 = [
  {id: 1, name: "a"},
  {id: 4, name: "d"},
];

let newArray = [...arr1, ...arr2].reduce((acc, item, index) => {
  acc.items.push(item);

  if (typeof acc.map[item.id] !== 'undefined') {
    acc.items[acc.map[item.id]] = null;
    acc.items[index] = null;
  }
  acc.map[item.id] = index;
  
  return acc
},  {map: {}, items: []}).items.filter(item => !!item)


console.log(newArray);