Retrieve objects in array if property matches another array









up vote
1
down vote

favorite












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









share|improve this question























  • Failed to mention how current solution differs from expected result or any errors encountered
    – charlietfl
    Nov 12 at 4:34











  • There's definitely a better way, but what do you mean by "simpler", what are you looking for?
    – CertainPerformance
    Nov 12 at 4:36










  • What are your criteria for "simpler"? It's difficult to conceive of a simpler method. There might be more efficient ones though, such as creating an index of contacts for reuse.
    – RobG
    Nov 12 at 4:41











  • Sorry I meant a more efficient way to go about doing this, without modifications to the arrays. The current solution provides the desired output but is there a more efficient method e.g. without using a forEach loop?
    – iBlehhz
    Nov 12 at 4:45














up vote
1
down vote

favorite












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









share|improve this question























  • Failed to mention how current solution differs from expected result or any errors encountered
    – charlietfl
    Nov 12 at 4:34











  • There's definitely a better way, but what do you mean by "simpler", what are you looking for?
    – CertainPerformance
    Nov 12 at 4:36










  • What are your criteria for "simpler"? It's difficult to conceive of a simpler method. There might be more efficient ones though, such as creating an index of contacts for reuse.
    – RobG
    Nov 12 at 4:41











  • Sorry I meant a more efficient way to go about doing this, without modifications to the arrays. The current solution provides the desired output but is there a more efficient method e.g. without using a forEach loop?
    – iBlehhz
    Nov 12 at 4:45












up vote
1
down vote

favorite









up vote
1
down vote

favorite











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









share|improve this question















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






javascript arrays typescript object angular6






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 12 at 5:32









Mamun

24.4k71428




24.4k71428










asked Nov 12 at 4:31









iBlehhz

748




748











  • Failed to mention how current solution differs from expected result or any errors encountered
    – charlietfl
    Nov 12 at 4:34











  • There's definitely a better way, but what do you mean by "simpler", what are you looking for?
    – CertainPerformance
    Nov 12 at 4:36










  • What are your criteria for "simpler"? It's difficult to conceive of a simpler method. There might be more efficient ones though, such as creating an index of contacts for reuse.
    – RobG
    Nov 12 at 4:41











  • Sorry I meant a more efficient way to go about doing this, without modifications to the arrays. The current solution provides the desired output but is there a more efficient method e.g. without using a forEach loop?
    – iBlehhz
    Nov 12 at 4:45
















  • Failed to mention how current solution differs from expected result or any errors encountered
    – charlietfl
    Nov 12 at 4:34











  • There's definitely a better way, but what do you mean by "simpler", what are you looking for?
    – CertainPerformance
    Nov 12 at 4:36










  • What are your criteria for "simpler"? It's difficult to conceive of a simpler method. There might be more efficient ones though, such as creating an index of contacts for reuse.
    – RobG
    Nov 12 at 4:41











  • Sorry I meant a more efficient way to go about doing this, without modifications to the arrays. The current solution provides the desired output but is there a more efficient method e.g. without using a forEach loop?
    – iBlehhz
    Nov 12 at 4:45















Failed to mention how current solution differs from expected result or any errors encountered
– charlietfl
Nov 12 at 4:34





Failed to mention how current solution differs from expected result or any errors encountered
– charlietfl
Nov 12 at 4:34













There's definitely a better way, but what do you mean by "simpler", what are you looking for?
– CertainPerformance
Nov 12 at 4:36




There's definitely a better way, but what do you mean by "simpler", what are you looking for?
– CertainPerformance
Nov 12 at 4:36












What are your criteria for "simpler"? It's difficult to conceive of a simpler method. There might be more efficient ones though, such as creating an index of contacts for reuse.
– RobG
Nov 12 at 4:41





What are your criteria for "simpler"? It's difficult to conceive of a simpler method. There might be more efficient ones though, such as creating an index of contacts for reuse.
– RobG
Nov 12 at 4:41













Sorry I meant a more efficient way to go about doing this, without modifications to the arrays. The current solution provides the desired output but is there a more efficient method e.g. without using a forEach loop?
– iBlehhz
Nov 12 at 4:45




Sorry I meant a more efficient way to go about doing this, without modifications to the arrays. The current solution provides the desired output but is there a more efficient method e.g. without using a forEach loop?
– iBlehhz
Nov 12 at 4:45












2 Answers
2






active

oldest

votes

















up vote
2
down vote



accepted










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






share|improve this answer




















  • I see. Thanks for your detailed explanation!! :)
    – iBlehhz
    Nov 12 at 6:39

















up vote
2
down vote













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








share|improve this answer


















  • 1




    Thanks for your solution! it works :)
    – iBlehhz
    Nov 12 at 5:05











  • @iBlehhz—yes, but "works" is not a measure of efficiency. ;-) This will be efficient where selectedContacts is small, but if it's not, an indexed solution may be better (assuming the cost of creating the index can be recovered).
    – RobG
    Nov 12 at 5:34











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53255988%2fretrieve-objects-in-array-if-property-matches-another-array%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
2
down vote



accepted










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






share|improve this answer




















  • I see. Thanks for your detailed explanation!! :)
    – iBlehhz
    Nov 12 at 6:39














up vote
2
down vote



accepted










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






share|improve this answer




















  • I see. Thanks for your detailed explanation!! :)
    – iBlehhz
    Nov 12 at 6:39












up vote
2
down vote



accepted







up vote
2
down vote



accepted






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






share|improve this answer












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







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 12 at 5:57









lucascaro

3,39611530




3,39611530











  • I see. Thanks for your detailed explanation!! :)
    – iBlehhz
    Nov 12 at 6:39
















  • I see. Thanks for your detailed explanation!! :)
    – iBlehhz
    Nov 12 at 6:39















I see. Thanks for your detailed explanation!! :)
– iBlehhz
Nov 12 at 6:39




I see. Thanks for your detailed explanation!! :)
– iBlehhz
Nov 12 at 6:39












up vote
2
down vote













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








share|improve this answer


















  • 1




    Thanks for your solution! it works :)
    – iBlehhz
    Nov 12 at 5:05











  • @iBlehhz—yes, but "works" is not a measure of efficiency. ;-) This will be efficient where selectedContacts is small, but if it's not, an indexed solution may be better (assuming the cost of creating the index can be recovered).
    – RobG
    Nov 12 at 5:34















up vote
2
down vote













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








share|improve this answer


















  • 1




    Thanks for your solution! it works :)
    – iBlehhz
    Nov 12 at 5:05











  • @iBlehhz—yes, but "works" is not a measure of efficiency. ;-) This will be efficient where selectedContacts is small, but if it's not, an indexed solution may be better (assuming the cost of creating the index can be recovered).
    – RobG
    Nov 12 at 5:34













up vote
2
down vote










up vote
2
down vote









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








share|improve this answer














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








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





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






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 12 at 5:24

























answered Nov 12 at 4:36









Mamun

24.4k71428




24.4k71428







  • 1




    Thanks for your solution! it works :)
    – iBlehhz
    Nov 12 at 5:05











  • @iBlehhz—yes, but "works" is not a measure of efficiency. ;-) This will be efficient where selectedContacts is small, but if it's not, an indexed solution may be better (assuming the cost of creating the index can be recovered).
    – RobG
    Nov 12 at 5:34













  • 1




    Thanks for your solution! it works :)
    – iBlehhz
    Nov 12 at 5:05











  • @iBlehhz—yes, but "works" is not a measure of efficiency. ;-) This will be efficient where selectedContacts is small, but if it's not, an indexed solution may be better (assuming the cost of creating the index can be recovered).
    – RobG
    Nov 12 at 5:34








1




1




Thanks for your solution! it works :)
– iBlehhz
Nov 12 at 5:05





Thanks for your solution! it works :)
– iBlehhz
Nov 12 at 5:05













@iBlehhz—yes, but "works" is not a measure of efficiency. ;-) This will be efficient where selectedContacts is small, but if it's not, an indexed solution may be better (assuming the cost of creating the index can be recovered).
– RobG
Nov 12 at 5:34





@iBlehhz—yes, but "works" is not a measure of efficiency. ;-) This will be efficient where selectedContacts is small, but if it's not, an indexed solution may be better (assuming the cost of creating the index can be recovered).
– RobG
Nov 12 at 5:34


















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53255988%2fretrieve-objects-in-array-if-property-matches-another-array%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

27

Top Tejano songwriter Luis Silva dead of heart attack at 64

Category:Rhetoric