Reputation: 1681
I need to compare two arrays and return the matches:
Array1
(13) ["0:EQSOLREENVIO", "1:EQPER", "2:EQCAN", "3:EQRECHKODOC", "4:EQAUS,EQCDE,EQDDE,EQINACCE,EQVAC", "5:EQINDEV", "6:EQCAMBIODI,EQENV,EQFECHA,EQFIESTA,EQINCITRASP", "7:EQENT", "8:EQDEV", "9:EQRCH", "10:EQADMIPDV", "11:EQCRE,EQRETENER", "12:EQRECOOFI"]
0: "0:EQSOLREENVIO"
1: "1:EQPER"
2: "2:EQCAN"
3: "3:EQRECHKODOC"
4: "4:EQAUS,EQCDE,EQDDE,EQINACCE,EQVAC"
5: "5:EQINDEV"
6: "6:EQCAMBIODI,EQENV,EQFECHA,EQFIESTA,EQINCITRASP"
7: "7:EQENT"
8: "8:EQDEV"
9: "9:EQRCH"
10: "10:EQADMIPDV"
11: "11:EQCRE,EQRETENER"
12: "12:EQRECOOFI"
length: 13
__proto__: Array(0)
Array2
(3) ["11", "0", "5"]
0: "11"
1: "0"
2: "5"
length: 3
__proto__: Array(0)
What I have tried:
const orderStatusCodes = this.orderInProgressCmsModel.orderStatusCodes.split("/");
const orderGroupsEditables = this.orderInProgressCmsModel.orderStatusLogEditables.split(",");
let groupFound = '';
const groupFound2 = [];
orderGroupsEditables.forEach((element2) => {
orderStatusCodes.forEach((element) => {
if (element.indexOf(element2) >= 0){
groupFound = element.split(":")[1];
groupFound2.push(groupFound);
}
});
});
Result:
(4) ["EQCRE,EQRETENER", "EQSOLREENVIO", "EQADMIPDV", "EQINDEV"]
0: "EQCRE,EQRETENER"
1: "EQSOLREENVIO"
2: "EQADMIPDV"
3: "EQINDEV"
length: 4
__proto__: Array(0)
When the numbers match from each array I need the code returned. I have been able to do this with the code I show but I would like to know if theres an easier way like using filter or something similar?
Upvotes: 0
Views: 85
Reputation: 8470
One thing to note is that depending on how big the arrays are, you might want to have a more performant algorithm. The solution presented in the question and the one supplied by @Mohammed Mortaga will loop through the second array for every element in the first array (in big O notation, that would be O(n*m)
). This is doing a lot more work than is needed. You really only need to loop through each array a single time (in big O notation, that would be O(n+m)
).
You can create a lookup table by looping through array1
that you could then use to lookup if the id exists (and readily have access to the corresponding code):
const regex = /^([^:]*):(.*)/;
const lookup = array1.reduce((acc, val) => {
const [, id, code] = regex.exec(val);
acc[id] = code;
return acc;
}, {});
Once you have your lookup table it is constant time complexity to get the code that corresponds to each element in your array2
(meaning for each item we don't need to search for a match, we can know in constant time if there is a match or not). Here you could use reduce
:
const codes = array2.reduce((acc, id) => {
const code = lookup[id];
if (code) {
acc.push(code);
}
return acc;
}, []);
or you could use a one-liner:
const codes = array2.filter(id => lookup[id]).map(id => lookup[id]);
The one-liner would be slightly less performant because it is doing two looping operations, but that is relatively minor if the array is pretty small in length (and the big O notation would still be the same but the readability is increased).
Upvotes: 2
Reputation: 139
Yes, you can achieve this using a single filter
function like so:
const array1 = ["0:EQSOLREENVIO", "1:EQPER", "2:EQCAN", "3:EQRECHKODOC", "4:EQAUS,EQCDE,EQDDE,EQINACCE,EQVAC", "5:EQINDEV", "6:EQCAMBIODI,EQENV,EQFECHA,EQFIESTA,EQINCITRASP", "7:EQENT", "8:EQDEV", "9:EQRCH", "10:EQADMIPDV", "11:EQCRE,EQRETENER", "12:EQRECOOFI"];
const array2 = ["11", "0", "5"];
const result = array1.filter(e => array2.indexOf(e.match(/\d+/)[0]) > -1); // ["0:EQSOLREENVIO", "5:EQINDEV", "11:EQCRE,EQRETENER"]
In short, this code iterates over the first array extracting the digits and checks if they exist or not in the second array.
Hope this helps!
Upvotes: 1