Retrieve objects in array if property matches another array

╄→гoц情女王★ 提交于 2021-01-28 16:31:44

问题


I want to create a new array containing contact objects if the value property in contacts matches the values in 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));
});

回答1:


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.

Say the length of contacts is N and the length of selectedContacts is M.

Since selectedContacts is a subset of contacts, we know 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)).

The code from the accepted answer iterates over contact (O(N)) and looks for a value in selectedContact which is O(M). This makes the algorithm equivalent, with 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.

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.

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. This would have similar lookup speeds (roughly O(1)).




回答2:


You can use Array.prototype.filter()

The filter() method creates a new array with all elements that pass the test implemented by the provided function.

and Array.prototype.includes()

The includes() method determines whether an array includes a certain element, returning true or false as appropriate.

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);


来源:https://stackoverflow.com/questions/53255988/retrieve-objects-in-array-if-property-matches-another-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!