如何从一个数组中未包含在第二个数组中的对象中最好地创建对象数组

时间:2019-07-08 19:25:14

标签: javascript arrays object

我想要一个数组,其中包含scrape对象中不存在的old对象中的对象。我实际使用的数组包含近100个对象。

下面的代码有效,但是我想知道是否有更有效的方法来获得相同的结果?

var old = [
  {a: 6, b: 3},
  {a: 1, b: 1}, 
  {a: 3, b: 3}
]

var scrape = [
  {a: 1, b: 1}, 
  {a: 5, b:5}
]

var nogood = []
var good =[]

scrape.forEach(es => {
  old.forEach(e => {
    if(e.a == es.a) {
      nogood.push(es)
    }
  })
})
console.log(nogood)

nogood.forEach(main =>   
  good = scrape.filter(e=> e.a!=main.a)  
)
console.log(good)

这是我的期望以及得到的:

good = {a:5, b:5}

4 个答案:

答案 0 :(得分:1)

我个人将通过以下方式解决此问题:

const old = [
  {a: 6, b: 3},
  {a: 1, b: 1}, 
  {a: 3, b: 3}
];

const scrape = [{a: 1, b: 1}, {a: 5, b:5}];

for (const item of old) {
  for (const i in scrape) {
    if (JSON.stringify(item) === JSON.stringify(scrape[i])) {
      scrape.splice(i, 1); //delete the previously scraped item
    }
  }
} 

console.log(scrape); //{a: 5, b:5}

这种方法的好处是:

  • 您不在乎所比较的对象具有哪些属性,    您只是在乎它们是否相同。
  • 速度很快    (比较JSON通常比遍历对象更快    比较每个属性)。
  • 将刮板拼接起来更简洁    数组,而不是添加“好”和“不好”的数组    过滤后的抓取数组。

可能的破坏者是,如果您要比较的对象包含方法,在这种情况下,通过JSON比较对象不是正确的方法。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

答案 1 :(得分:1)

如果我们的数组oldscrape的大小分别为MN,则所有传统方法的复杂度都为O(M * N),因为需要将数组scrape中的每个条目与数组old中存在的条目进行比较,以找出是否匹配。

第二种更有效的方法是在第一个数组上创建哈希表,通常在较大的数组上(此处为old),然后在第二个数组(此处为scrape)上进行迭代,这很复杂的O(M + N)

如果MN的大小足够大,则差异会显示出来。例如,如果M=100N=200,前一个需要比较20000个对象,而后一个只需要比较300

请看一下这段代码:

const old = [
  {a: 6, b: 3},
  {a: 1, b: 1},
  {a: 3, b: 3}
]

const scrape = [
  {a: 1, b: 1},
  {a: 5, b:5}
]

// create hash map using built-in Javascript Map
const pair = old.map(x => [JSON.stringify(x), true])
const map = new Map(pair)

// filter those object does not exist in hash map
const good = scrape.filter(x => !map.has(JSON.stringify(x)))
console.log(good)

答案 2 :(得分:0)

这样的事情怎么样?

const good = scrape.filter((sEl) => {
  return !old.some(oEl => oEl.a === sEl.a);
})

这避免了嵌套的forEach循环,并且.some将在找到单个真实条件后立即返回,从而避免在“旧”数组的早期存在元素时进行过多搜索。

答案 3 :(得分:0)

可能类似于:

var old = [
  {a: 6, b: 3},
  {a: 1, b: 1}, 
  {a: 3, b: 3}
]

var scrape = [
  {a: 1, b: 1}, 
  {a: 5, b:5}
]

var result = scrape.filter(s => old.findIndex(o => o.a === s.a) === -1);
console.log(result);