从两个角度对象列表中获得唯一结果

时间:2018-09-23 23:16:44

标签: javascript angular typescript

嗨,我有两个对象列表,我试图在我的angular 4组件的新列表中获取唯一对象。

IList1 l1=[ {"_id":'a1', "name": "john"},
            _id":'a2', "name": "adam"},
             _id":'a3', "name": "jenny"}];

IList1 l2=[ {"_id":'a1', "name": "john"},
            _id":'b5', "name": "joe"},
             _id":'a3', "name": "jenny"}];

我正在尝试编写代码,以便可以在新列表中获得唯一项,因此

IList1 result=[_id":'b5', "name": "joe"}]

我正在遵循我的代码以获取结果列表

var len1=this.l1.length;
var len2=this.l2.lenth;
Ilist1 result=[];
for(var i=0; i<l1; i++)
   { 
     for(var y=0; y<l2; y++)
       {
         if(this.l1[i]._id !== this.l2[y]._id)
         this.result.push(this.l2[y])
       }
   }
上面的

代码给出的结果基本上符合我的要求,它吐出了两个列表中的公共对象。我试图将!==更改为==仍然没有给出预期的结果。 请让我知道如何解决它,以使唯一记录进入结果列表。谢谢

2 个答案:

答案 0 :(得分:0)

这就是您当前的代码所发生的事情

这是您的代码用英语执行的操作:

  1. 对于列表l1(for(var i=0; i<l1; i++))的每个元素;

  2. 遍历列表l2(for(var y=0; y<l2; y++));

  3. 如果l1的元素不在l2(if(this.l1[i]._id !== this.l2[y]._id))的所有元素上

  4. 将其添加到列表(this.result.push(this.l2[y])

那么哪里出了问题,步骤3转化为执行,我们在循环的一部分的第一次迭代中得到了

l1[0] !== l2[0] ("a2" !== "a1") // true- result = []
l1[0] !== l2[1] ("a2" !== "b5") // true - result = [{"_id":'b5', "name": "joe"}]
l1[0] !== l2[2] ("a2" !== "a3") // true - result = [{"_id":'b5', "name": "joe"}, {"_id":'a3', "name": "jenny"}]

在第二次迭代中:

l1[1] !== l2[0] ("a1" !== "a1") // false - result = [{"_id":'b5', "name": "joe"}, {"_id":'a3', "name": "jenny"}, {"_id":'a1', "name": "john"}]
l1[1] !== l2[1] ("a1" !== "b5") // true - result = [{"_id":'b5', "name": "joe"}, {"_id":'a3', "name": "jenny"}, {"_id":'a1', "name": "john"},{"_id":'b5', "name": "joe"}]
l1[1] !== l2[2] ("a1" !== "a3") // true - result = [{"_id":'b5', "name": "joe"}, {"_id":'a3', "name": "jenny"}, {"_id":'a1', "name": "john"},{"_id":'b5', "name": "joe"},{"_id":'b5', "name": "joe"}]

因此您可以看到您的情况不正常,因为所有其他与当前被测元素都不相同的元素都将被添加到列表中。

为了简化逻辑,让我们连接两个数组并应用与之前相同的逻辑,只是两次遍历相同的串联列表,并使用布尔值告诉您元素是否重复:

var l1 = [{
    "_id": 'a1',
    "name": "john"
  },
  {
    "_id": 'a2',
    "name": "adam"
  },
  {
    "_id": 'a3',
    "name": "jenny"
  }
];

var l2 = [{
    "_id": 'a1',
    "name": "john"
  },
  {
    "_id": 'b5',
    "name": "joe"
  },
  {
    "_id": 'a3',
    "name": "jenny"
  }
];
var result = [];
var joinedArray = l1.concat(l2);
for (var i = 0; i < joinedArray.length; i++) {
  var isDuplicate = false;
  for (var y = 0; y < joinedArray.length; y++) {
    if (i != y && this.joinedArray[i]._id === this.joinedArray[y]._id)
      isDuplicate = true;
  }
  if (!isDuplicate)
    this.result.push(joinedArray[i]);
}

console.log(result)

此解决方案不是最有效或最逻辑的解决方案,但应该更容易理解,因为它更接近您的原始逻辑。

答案 1 :(得分:0)

我可能会在以id为键的哈希中计算对象。然后filter()map()将对象计数为计数为1的项目。

let l1=[ {"_id":'a1', "name": "john"},{"_id":'a2', "name": "adam"},{"_id":'a3', "name": "jenny"}];
let l2=[ {"_id":'a1', "name": "john"},{"_id":'b5', "name": "joe"},{"_id":'a3', "name": "jenny"}];

// make an object that counts the items
// only need to store the last item since you're looking for uniques
let counts = [...l1, ...l2].reduce((obj, item) =>{
    if (obj[item._id]) obj[item._id].count++
    else obj[item._id] = {count:1, object: item}
    return obj
}, {})

// filter that object by count and return the objects
let filtered = Object.values(counts).filter(item => item.count === 1).map(item => item.object)
console.log(filtered)