[英]Retrieve objects in array if property matches another array
I want to create a new array containing contact objects if the value property in contacts matches the values in selectedContact
. 如果联系人中的value属性与selectedContact
中的值匹配,我想创建一个包含联系人对象的新数组。 Any simpler way to do this? 还有更简单的方法吗?
selectedContact: number[] = [0,2] //value
contacts: Contact[] = [{
firstName:"Dan";
lastName:"Chong";
email:"danc@mail.com";
value:0;
},
{
firstName:"Mark";
lastName:"Wong";
email:"markw@mail.com";
value:1;
},
{
firstName:"Layla";
lastName:"Sng";
email:"layla@mail.com";
value: 2;
}]
Intended final result: 预期的最终结果:
newArray = [{
firstName:"Dan";
lastName:"Chong";
email:"danc@mail.com";
value:0;
},{
firstName:"Layla";
lastName:"Sng";
email:"layla@mail.com";
value:2;
}];
My current solution: 我当前的解决方案:
const newArray: Contact[] = [];
this.selectedContact.forEach(index => {
newArray.push(this.contacts.find(c => c.value === index));
});
You can use Array.prototype.filter() 您可以使用Array.prototype.filter()
The
filter()
method creates a new array with all elements that pass the test implemented by the provided function.filter()
方法创建一个新数组,其中所有元素都通过了由提供的函数实现的测试。
and Array.prototype.includes() 和Array.prototype.includes()
The includes() method determines whether an array includes a certain element, returning true or false as appropriate. includes()方法确定数组是否包含某个元素,并在适当时返回true或false。
Working Code Example: 工作代码示例:
var selectedContact = [0,2]; var contacts = [{ firstName: "Dan", lastName: "Chong", email: "danc@mail.com", value: 0 }, { firstName: "Mark", lastName: "Wong", email: "markw@mail.com", value: 1 }, { firstName: "Layla", lastName: "Sng", email: "layla@mail.com", value: 2 }] let newArray = contacts.filter(c => selectedContact.includes(c.value)); console.log(newArray);
In terms of performance, it would be better to iterate over selectedContacts
rather than contacts
, especially since contacts
are indexed (as an array) and you are selecting through the index. 就性能而言,最好在selectedContacts
上进行迭代,而不要在contacts
上进行迭代,尤其是因为已对contacts
索引(作为数组)并且您正在通过索引进行选择。
Say the length of contacts
is N
and the length of selectedContacts
is M
. 假设contacts
的长度为N
,而selectedContacts
的长度为M
Since selectedContacts
is a subset of contacts
, we know M <= N
. 由于selectedContacts
是contacts
的子集,因此我们知道M <= N
For large databases of contacts, this difference could be significant. 对于大型的联系人数据库,这种差异可能会很大。
The code in the question: 问题中的代码:
this.selectedContact.forEach(index => {
newArray.push(this.contacts.find(c => c.value === index));
});
Has O(M*N)
since it iterates over selectedContact
O(M)
and on each iteration it find a value in contacts
( O(N)
). 具有O(M*N)
因为它遍历selectedContact
O(M)
并且在每次迭代时都在contacts
( O(N)
)中找到一个值。
The code from the accepted answer iterates over contact
( O(N)
) and looks for a value in selectedContact
which is O(M)
. 接受的答案中的代码遍历contact
( O(N)
),并在selectedContact
寻找值为O(M)
。 This makes the algorithm equivalent, with O(N*M)
这使得算法等效于O(N*M)
In your example, you already have a cheap way of looking up contacts by number since contacts
is an array and your indexes are simply the index in the array. 在您的示例中,由于contacts
是一个数组,而您的索引只是该数组中的索引,因此您已经有一种便宜的方法来按号码查找联系人。
This means you can use code like this: 这意味着您可以使用如下代码:
return this.selectedContact.map(index => this.contacts[index]);
Since accessing an array element by index has O(1)
, this would have O(M)
which is the smallest of the sizes. 由于按索引访问数组元素具有O(1)
,因此它将具有O(M)
,这是最小的大小。
If you can't use the array index as a key, you can use other data structures, like a Map
where the id is the key, and the contact is the value. 如果不能将数组索引用作键,则可以使用其他数据结构,例如Map
,其中id是键,而contact是值。 This would have similar lookup speeds (roughly O(1)
). 这将具有相似的查找速度(大约为O(1)
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.