降低对象列表之间比较的复杂性O ^ 2

时间:2017-10-11 19:36:56

标签: javascript arrays data-structures

我有两个对象列表:

list1 = [{value: 'X'}, {value: 'Y'}, ..., {value: 'Z'}];
list2 = [{value: 'A'}, {value: 'B'}, ..., {value: 'C'}];

我有这段代码检查list2中的值是否在list1中。如果是代码没有做任何事情,如果没有,它应该添加到list1(这将创建一个新列表,list3)。这意味着我在两个列表之间进行联合而不保留重复值。

for (let i = list2.length-1; i >= 0; i--) {
  let item = list2[i];
  let shared = false;
  for (let j = list1.length-1; j >=0; j--) {
    let childItem = list1[j];
    if (item.value === childItem.value) {
      shared = true;
      break;
    }
  }
  if (!shared) { newValues.push(item); }
}
list3 = list1.concat(newValues);

这很好用,但我想知道我是否可以改进这个O(n * m)。

我不确定列表是否总是默认排序,但是从我看到的那两个(list1和list2)总是按值排序。

示例:

var list1 = [{value: 'bar'}, {value: 'baz'}, {value: 'foo'}, {value: 'foz'}];
var list2 = [{value: 'bar'}, {value: 'foo'}, {value: 'test'}, {value: 'testz'}];
var list3 = union(list1, list2);
list3 = [{value: 'bar'}, {value: 'baz'}, {value: 'foo'}, {value: 'foz'}, {value: 'test'}, {value: 'testz'}];

2 个答案:

答案 0 :(得分:3)

根据集合中的值创建一组list1和过滤器list2的值,然后再将其结合到list1

var list1 = [{value: 'bar'}, {value: 'baz'}, {value: 'foo'}, {value: 'foz'}];
var list2 = [{value: 'bar'}, {value: 'foo'}, {value: 'test'}, {value: 'testz'}];

const union = (list1, list2) => list1.concat(
  list2.filter(function({ value }) { // filter list2
    return !this.has(value); // filter out items which value is in the set
  }, new Set(list1.map(({ value }) => value))) // the set of list1 values
);

const list3 = union(list1, list2);

console.log(list3);

答案 1 :(得分:2)

您可以使用单个循环并将值存储在一个集合中以供稍后检查。复杂性:O(n)。



var list1 = [{ value: 'X' }, { value: 'Y' }, { value: 'C' }, { value: 'Z' }],
    list2 = [{ value: 'A' }, { value: 'B' }, { value: 'C' }, { value: 'D' }],
    list3 = list1
        .concat(list2)
        .filter((s => ({ value }) => !s.has(value) && s.add(value))(new Set));

console.log(list3);

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