Reputation: 97
I'm trying to match two arrays and extract the matching values into a new array while keeping it in the same order as the second array. For example:
let strArr1 = ['a', 'p', 'p', 'l', 'e'];
let strArr2 = ['p','p','a','e', 'l', 'l', 'k'];
let newArr = [];
// Wanted output: ['p', 'p', 'a', 'e', 'l']
So what I'm trying to do here is remove the extra characters in the second array. The code I've come up with so far:
for (let i=0; i < strArr1.length; i++){
for (let j=0; j < strArr2.length; j++){
if (strArr1[i]==strArr2[j]){
newArr.push(strArr2[i])
}
}
}
For some reason, the output becomes:
['p', 'p', 'p', 'a', 'a', 'e', 'e', 'l']
I've also tried the filter method. It's closer to the results I want.
const newArr = strArr2.filter(value => strArr1.includes(value));
But the output becomes:
['p', 'p', 'a', 'e', 'l', 'l']
Upvotes: 1
Views: 1996
Reputation: 478
const newArr = strArr2.filter(value => strArr1.includes(value) && arr.splice(arr.indexOf(value), 1));
This works :)
Upvotes: 1
Reputation: 5054
There are two mistakes in your code though, you are pushing strArr2[i] in the newArr
although, you used j
to iterate over strArr2. And when you find a match to push into newArr
, you need to break the loop and move to the next element in strArr2
.
In order to keep the order in strArr2 you need to change the order of the for loop,
for (let i=0; i < strArr2.length; i++){
for (let j=0; j < strArr1.length; j++){
if (strArr1[j]==strArr2[i]){
newArr.push(strArr2[i])
j += strArr1.length;
}
}
}
The complexity is O(n^2) You can optimize the code by doing the following,
let strArr1 = ['a', 'p', 'p', 'l', 'e'];
let strArr2 = ['p','p','a','e', 'l', 'l', 'k'];
let newArr = [];
// Wanted output: ['p', 'p', 'a', 'e', 'l']
newArr = strArr2.filter(item => strArr1.includes(item));
console.log(newArr);
['p', 'p', 'a', 'e', 'l', 'l']
is correct output as there is two l
in the strArr2
.
If you want to match each value once, you can remove the value from strArr1
after finding a match.
let strArr1 = ['a', 'p', 'p', 'l', 'e'];
let strArr2 = ['p','p','a','e', 'l', 'l', 'k'];
let newArr = [];
console.log('abc');
newArr = strArr2.reduce((prev, curr) => {
if(strArr1.includes(curr)) {
prev.push(curr);
strArr1.splice(strArr1.indexOf(curr), 1);
}
return prev;
}, []);
console.log(newArr);
Upvotes: 1
Reputation: 91
You can try something like this
strArr1 = strArr1.reduce((acc, v)=> ({ ...acc, [v]: (acc[v] ? (++acc[v]) : 1) }), {})
strArr2.filter(v => !!(strArr1[v]--) )
Upvotes: 1