【问题标题】:compare 2 arrays to see if objects exist比较 2 个数组以查看对象是否存在
【发布时间】:2016-06-30 21:29:26
【问题描述】:

数组 1 = [对象]

数组 2 = [对象,对象]

假设在 array 1 中的对象是:

 {
   'name': 'apple',
   'id': ''
 }

在数组 2 中:

对象1:

 {
  'name': 'bananna',
  'id': 2
 }

对象 2:

 {
  'name': 'apple',
  'id': 1
 }

我想看看数组1中的对象是否在数组2中,如果是,将array1的id设置为相同的id。它应该返回true或对象本身,然后在数组1中,id应该更改为1。

不要以为我的尝试很快。顺便说一句,两个数组都可以是任意大小。

  var itemFrom1;
  for (var a = 0; a < array1.length; a++) {
    itemFrom1 = array1[a];

    for(var b = 0; b < array2.length; b++) {                               
      if (itemFrom1.name === array2[b].name) {
        itemFrom1.id = array2[b].id;
      }
    }
  }

也许我可以使用 underscore.js 或更简单的方法。

var matched=_.findWhere(array2,{name:array1.name}) 

注意:需要此功能适用于所有浏览器。

【问题讨论】:

  • 那个流浪的美元符号在那里做什么?
  • 您正在检查相等的索引......也就是说,您正在检查 array1 的第一个元素是否与 array2 的第一个元素具有相同的名称。然后您将检查第二个元素是否与第二个元素匹配,依此类推。
  • @JimNastos 是的,我意识到了,所以我该如何解决它,因为我的方法是错误的。索引可以不同
  • 正如 Jim 所说,您需要两个嵌套循环,而不是一个循环。对于 A 中的每个元素,您需要将其与 B 中的每个元素进行比较。
  • @JosephYoung 喜欢这样吗?

标签: javascript arrays underscore.js javascript-objects


【解决方案1】:

你可以试试这个:

它的作用是遍历list1 中的每个元素,根据list2 中的每个元素检查名称,并添加匹配的ID。

var list1 = [
  { name: "apple" },
  { name: "grape" },
  { name: "orange" },
  { name: "watermelon" }
];
var list2 = [
  { name: "apple", id: 1 },
  { name: "grapefruit", id: 2 },
  { name: "grape", id: 3 }
];

for(item in list1) {
  var match = list2.filter(function(obj) {
    return obj.name == list1[item].name;
  })[0] || false;
  if(match)
    list1[item].id = match.id;
}

console.log(list1);

应您的要求,我tested both of ours on JSFiddle 并意识到我的速度要慢得多(根据performance.now(),0.3799999999999386 毫秒而不是 0.07999999999998408 毫秒)。哎呀。

您的方法很有效,并且可能尽可能简单。我会说坚持下去。

【讨论】:

  • 您不需要在列表 1 中定义 id 吗?而且,所以这会将葡萄设置为 id 2,苹果设置为 id 1,在列表 1 中,对吗?
  • 另外,这比我现在的 2 个 for 循环快吗?
  • @Angular 你不需要在list1 中定义id 属性,除非你想要一种默认值,以防list2 中没有匹配项。是的,grape 的 id 将设置为 2,apple 的 id 将设置为 1(您可以通过运行 sn-p 看到这一点)。
  • 在速度方面,@Angular,我不确定速度差异。我现在就去看看。
【解决方案2】:

我建议对list1 的元素使用哈希表,并将其作为添加id 的参考。该提案的复杂度为 O(n + m)

var list1 = [{ name: "apple" }, { name: "grape" }, { name: "orange" }, { name: "watermelon" }],
    list2 = [{ name: "apple", id: 1 }, { name: "grapefruit", id: 2 }, { name: "grape", id: 3 }],
    hash = Object.create(null);

list1.forEach(function (a) {
    hash[a.name] = a;
});

list2.forEach(function (a) {
    if (hash[a.name]) {
        hash[a.name].id = a.id;
    }
});

console.log(list1);

或者使用Map,如果你的用户代理支持的话。

var list1 = [{ name: "apple" }, { name: "grape" }, { name: "orange" }, { name: "watermelon" }],
    list2 = [{ name: "apple", id: 1 }, { name: "grapefruit", id: 2 }, { name: "grape", id: 3 }],
    map = new Map();

list1.forEach(a => map.set(a.name, a));
list2.forEach(a => (map.get(a.name) || {}).id = a.id);

console.log(list1);

【讨论】:

  • 为什么使用哈希对象而不是哈希映射?是为了兼容吗?
  • @mortezaT,实际上ObjectMap 更可靠。
  • 你的回答太宽泛了。如果您有任何解释过的答案,您可以发送链接吗?
  • 地图兼容性不太好bad.
【解决方案3】:

您的实现没问题,当在 array2 中找到该项目时,我将在第二个循环中添加一个 break;,否则您将遍历 array2 中的所有其他项目,假设您正在寻找的项目是第一个,如果你不破坏第二个 for-loop ,你将遍历下一个 N

  var itemFrom1;
  for (var a = 0; a < array1.length; a++) {
    itemFrom1 = array1[a];

    for(var b = 0; b < array2.length; b++) {                               
      if (itemFrom1.name === array2[b].name) {
        itemFrom1.id = array2[b].id;
        break; // Stops the second loop, go on with the next value from array1!
      }
    }
  }

【讨论】:

    猜你喜欢
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-10
    • 1970-01-01
    • 2018-06-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多