Reputation: 586
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:"[email protected]";
value:0;
},
{
firstName:"Mark";
lastName:"Wong";
email:"[email protected]";
value:1;
},
{
firstName:"Layla";
lastName:"Sng";
email:"[email protected]";
value: 2;
}]
Intended final result:
newArray = [{
firstName:"Dan";
lastName:"Chong";
email:"[email protected]";
value:0;
},{
firstName:"Layla";
lastName:"Sng";
email:"[email protected]";
value:2;
}];
My current solution:
const newArray: Contact[] = [];
this.selectedContact.forEach(index => {
newArray.push(this.contacts.find(c => c.value === index));
});
Upvotes: 1
Views: 1306
Reputation: 19267
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)
).
Upvotes: 2
Reputation: 68933
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: "[email protected]",
value: 0
},
{
firstName: "Mark",
lastName: "Wong",
email: "[email protected]",
value: 1
},
{
firstName: "Layla",
lastName: "Sng",
email: "[email protected]",
value: 2
}]
let newArray = contacts.filter(c => selectedContact.includes(c.value));
console.log(newArray);
Upvotes: 2