如何从不同数组中的任何对象中返回具有唯一键值对的第一个对象?

huangapple go评论75阅读模式
英文:

Typescript: How can I return the first object in an array which has a unique key value pair from any objects in a different array?

问题

我想要返回一个对象数组中第一个没有与另一个数组中任何对象匹配的id的项目。例如,

array1 = [
 { name: "object1", id: 1, coordinates: undefined}
 { name: "object2", id: 2, coordinates: undefined}
 { name: "object3", id: 3, coordinates: undefined}
 { name: "object4", id: 4, coordinates: undefined}
 { name: "object5", id: 5, coordinates: undefined}
]



array2 = [
 { name: "object1", id: 1, coordinates: [3,2]}
 { name: "object2", id: 2, coordinates: [1,1]}
 { name: "object3", id: 3, coordinates: [3,6]}
]

应该返回

{ name: "object4", id: 4, coordinates: undefined}

我想要返回数组1中第一个不具有与数组2中任何对象匹配的id的项目。 (我不能仅仅将对象作为整体进行比较,因为可能存在其他不同的键值对。我只关心id。)

我正在尝试:

const firstUniqueItem = find(array1, function (object1) {
  return !array2.some((object2) => {object2.id === object1.id})
});

当array2为空时,这将起作用,但是当array2具有具有匹配id的对象时,仍然只返回array1的第一个项目。

我需要修复什么?是否有更好的方法来实现这个目标?

英文:

I want to return the first item in an array of objects that does not have a matching id to any object in a separate array. For example,

arrary1 = [
 { name: "object1", id: 1, coordinates: undefined}
 { name: "object2", id: 2, coordinates: undefined}
 { name: "object3", id: 3, coordinates: undefined}
 { name: "object4", id: 4, coordinates: undefined}
 { name: "object5", id: 5, coordinates: undefined}
]

and 

array2 = [
 { name: "object1", id: 1, coordinates: [3,2]}
 { name: "object2", id: 2, coordinates: [1,1]}
 { name: "object3", id: 3, coordinates: [3,6]}
]

Should return:

{ name: "object4", id: 4, coordinates: undefined}

I want to return the first item in array1 that does not have the same id as any of the objects in array2. (I cannot just compare the objects as a whole because there might be other differing key value pairs. I only care about the id.)

I am trying:

    const firstUniqueItem = find(array1, function (object1) {
      return !array2.some((object2) => {object2.id === object1.id})
    });

This will work when array2 is empty, but still just returns the first item of array1 when array2 has has an object with a matching id.

What do I need to fix? Is there a better way to accomplish this?

答案1

得分: 1

一种方法是过滤 array1 并删除任何与 array2 的匹配项,然后取第一个项目。

array1.filter(a => !array2.find(b => b.id === a.id))[0] || false

末尾的 || false 提供了一个布尔值,以防没有匹配项。否则,您将得到 undefined

英文:

One way is to filter array1 and remove any occurrence of array2, then take the first item.

array1.filter(a => !array2.find(b => b.id==a.id))[0] || false

The || false at the end gives you a boolean just in case there isn't a match. Otherwise you'd get undefined

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

let array1 = [
 { name: &quot;object1&quot;, id: 1, coordinates: undefined},
 { name: &quot;object2&quot;, id: 2, coordinates: undefined},
 { name: &quot;object3&quot;, id: 3, coordinates: undefined},
 { name: &quot;object4&quot;, id: 4, coordinates: undefined},
 { name: &quot;object5&quot;, id: 5, coordinates: undefined}
]

let array2 = [
 { name: &quot;object1&quot;, id: 1, coordinates: [3,2]},
 { name: &quot;object2&quot;, id: 2, coordinates: [1,1]},
 { name: &quot;object3&quot;, id: 3, coordinates: [3,6]}
]

let answer = array1.filter(a =&gt; !array2.find(b =&gt; b.id==a.id))[0] || false;
console.log(answer)

<!-- end snippet -->

答案2

得分: 1

正如@carcigenicate在评论中提到的,您传递给some()的函数没有返回值。

关于您的代码还有一些其他奇怪的地方,创建一个真正运行的代码片段会有所帮助。例如,您将第一个数组声明为arrary1,但在使用时却写成了array。另外,您使用了一个在JavaScript中不存在的find(array1)函数,我猜您是指array1.find()

以下是您提供的代码段的翻译:

array1 = [
 { name: "object1", id: 1, coordinates: undefined},
 { name: "object2", id: 2, coordinates: undefined},
 { name: "object3", id: 3, coordinates: undefined},
 { name: "object4", id: 4, coordinates: undefined},
 { name: "object5", id: 5, coordinates: undefined}
]

array2 = [
 { name: "object1", id: 1, coordinates: [3,2]},
 { name: "object2", id: 2, coordinates: [1,1]},
 { name: "object3", id: 3, coordinates: [3,6]}
]

// 应返回:
// { name: "object4", id: 4, coordinates: undefined}

const firstUniqueItem = array1.find(function (object1) {
  return !array2.some((object2) => {
    return object2.id === object1.id
  })
});
    
console.log(`firstUniqueItem: ${JSON.stringify(firstUniqueItem)}`)

当然,这是非常低效的。如果array2中有1000个元素,而array1中有1001个元素,您可能需要进行一百万次比较才能找到不在array2中的元素。您可以通过首先创建一个具有array2中的id作为属性名称且值为'true'(或任何真值)的对象来提高效率。

const mappedIds = array2.reduce((prev, curr) => {
  prev[curr.id] = true;
  return prev;
}, {});

const firstUniqueItem = array1.find(x => !mappedIds[x.id]);

希望这可以帮助您理解代码的功能。

英文:

As @carcigenicate mentions in his comment, the function you pass to some() does not return the value.

There are a few other weird things about your code, creating an actual snippet that ran would help. For instance your first array is declared as arrary1 but used as array. Also you use a find(array1) function that doesn't exist in javascript, I assume you mean array1.find().

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

array1 = [
 { name: &quot;object1&quot;, id: 1, coordinates: undefined},
 { name: &quot;object2&quot;, id: 2, coordinates: undefined},
 { name: &quot;object3&quot;, id: 3, coordinates: undefined},
 { name: &quot;object4&quot;, id: 4, coordinates: undefined},
 { name: &quot;object5&quot;, id: 5, coordinates: undefined}
]

array2 = [
 { name: &quot;object1&quot;, id: 1, coordinates: [3,2]},
 { name: &quot;object2&quot;, id: 2, coordinates: [1,1]},
 { name: &quot;object3&quot;, id: 3, coordinates: [3,6]}
]

//Should return:
//{ name: &quot;object4&quot;, id: 4, coordinates: undefined}

const firstUniqueItem = array1.find(function (object1) {
  return !array2.some((object2) =&gt; {
    return object2.id === object1.id
  })
});
    
console.log(`firstUniqueItem: ${JSON.stringify(firstUniqueItem)}`)

<!-- end snippet -->

Of course this is horribly inefficient. If you have 1000 elements in array2 and 1001 elements in array1, you could be doing a million comparisons to find the one element that isn't in array2. You can make this faster by first creating an object with property names that are the ids in array2 with values 'true' (or anything truthy).

const mappedIds = array2.reduce((prev, curr) =&gt; {
  prev[curr.id] = true;
  return prev;
}, {});

const firstUniqueItem = array1.find(x =&gt; !mappedIds[x.id]);

huangapple
  • 本文由 发表于 2023年6月22日 08:10:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/76527869.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定