admin管理员组文章数量:1401444
I have a situation where I need to pare and find mon values over two arrays. I am clear on how to do it with one, but not sure how to do it in this case.
My first array looks like this:
[ { kind: 'E',
path: [ 'short_name' ],
lhs: 'testing',
rhs: 'testing1' },
{ kind: 'E',
path: [ 'agent_name' ],
lhs: 'testing',
rhs: 'testing2' } ]
The array above represents information pertaining to what changed on a document.
My second array looks like this:
[ { lhs: 'legacyId', rhs: 'id_number' },
{ lhs: 'name.short', rhs: 'short_name' },
{ lhs: 'name.long', rhs: 'agent_name' },
{ lhs: 'gender', rhs: 'gender' },
{ lhs: 'dob', rhs: 'date_of_birth' } ]
What I need to do is loop through and find mon values for "path" in the first array's elements, and the second array's "rhs" value.
So according to my examples here, I should end up with these values being found: short_name
and agent_name
.
How could I write a loop to do this over the two arrays?
I have a situation where I need to pare and find mon values over two arrays. I am clear on how to do it with one, but not sure how to do it in this case.
My first array looks like this:
[ { kind: 'E',
path: [ 'short_name' ],
lhs: 'testing',
rhs: 'testing1' },
{ kind: 'E',
path: [ 'agent_name' ],
lhs: 'testing',
rhs: 'testing2' } ]
The array above represents information pertaining to what changed on a document.
My second array looks like this:
[ { lhs: 'legacyId', rhs: 'id_number' },
{ lhs: 'name.short', rhs: 'short_name' },
{ lhs: 'name.long', rhs: 'agent_name' },
{ lhs: 'gender', rhs: 'gender' },
{ lhs: 'dob', rhs: 'date_of_birth' } ]
What I need to do is loop through and find mon values for "path" in the first array's elements, and the second array's "rhs" value.
So according to my examples here, I should end up with these values being found: short_name
and agent_name
.
How could I write a loop to do this over the two arrays?
Share Improve this question asked Jul 12, 2019 at 13:37 ReyRey 1,4332 gold badges17 silver badges32 bronze badges4 Answers
Reset to default 6You can reduce
the 1st array and use a forEach
loop over the second array to see if each of the values are equal, then push the value to the accumulator:
const arr1 = [{ kind: 'E', path: [ 'short_name' ], lhs: 'testing', rhs: 'testing1' }, { kind: 'E', path: [ 'agent_name' ], lhs: 'testing', rhs: 'testing2' }]
const arr2 = [{ lhs: 'legacyId', rhs: 'id_number' }, { lhs: 'name.short', rhs: 'short_name' }, { lhs: 'name.long', rhs: 'agent_name' }, { lhs: 'gender', rhs: 'gender' }, { lhs: 'dob', rhs: 'date_of_birth' }]
const mon = arr1.reduce((a, o1) => {
const match = arr2.find(o2 => o1.path[0] === o2.rhs)
match && a.push(match.rhs)
return a
}, [])
console.log(mon)
If you truly wanted to, you could write this in one line with a find instead of a second reduce:
const a = [{ kind: 'E', path: [ 'short_name' ], lhs: 'testing', rhs: 'testing1' }, { kind: 'E', path: [ 'agent_name' ], lhs: 'testing', rhs: 'testing2' }]
const b = [{ lhs: 'legacyId', rhs: 'id_number' }, { lhs: 'name.short', rhs: 'short_name' }, { lhs: 'name.long', rhs: 'agent_name' }, { lhs: 'gender', rhs: 'gender' }, { lhs: 'dob', rhs: 'date_of_birth' }]
const mon = a.reduce((a, o1) => (a.push(b.find(o2 => o1.path[0] === o2.rhs).rhs), a), [])
console.log(mon)
Or, for a more performant solution ;) You could use a set:
const a = [{ kind: 'E', path: [ 'short_name' ], lhs: 'testing', rhs: 'testing1' }, { kind: 'E', path: [ 'agent_name' ], lhs: 'testing', rhs: 'testing2' }]
const b = [{ lhs: 'legacyId', rhs: 'id_number' }, { lhs: 'name.short', rhs: 'short_name' }, { lhs: 'name.long', rhs: 'agent_name' }, { lhs: 'gender', rhs: 'gender' }, { lhs: 'dob', rhs: 'date_of_birth' }]
var monValues = []
var set = new Set([])
for (let i = 0; i < a.length; i++) {
const value = a[i].path[0]
if (!set.has(value)) set.add(value)
}
for (let i = 0; i < b.length; i++) {
const val = b[i].rhs
if (set.has(val)) monValues.push(val)
}
console.log(monValues)
You can use a simply for
inside a for
...
This is the most simple (maybe not the most performatic) way you can do that, getting the value from first array, then looping the second one. If a value is found, then push it to another array (results
) and break the second loop (there's no need to still running if a value already match).
var a = [ { kind: 'E',
path: [ 'short_name' ],
lhs: 'testing',
rhs: 'testing1' },
{ kind: 'E',
path: [ 'agent_name' ],
lhs: 'testing',
rhs: 'testing2' } ]
var b =[ { lhs: 'legacyId', rhs: 'id_number' },
{ lhs: 'name.short', rhs: 'short_name' },
{ lhs: 'name.long', rhs: 'agent_name' },
{ lhs: 'gender', rhs: 'gender' },
{ lhs: 'dob', rhs: 'date_of_birth' } ]
var results = [];
for (var i = 0; i < a.length; i++){
var path = a[i].path;
for (var j = 0; j < b.length; j++){
var rhs = b[j].rhs;
if (rhs == path){
results.push(b[j].rhs)
break;
}
}
}
console.log(results)
You can do it in O(n^2) time by nesting a loop and searching through the second loop for every value of the first loop, or you can use a hashmap to do it in O(n) time. In JavaScript we use objects for that because their values can be accessed in O(1) time.
Example:
const array1 = [
{ kind: "E", path: ["short_name"], lhs: "testing", rhs: "testing1" },
{ kind: "E", path: ["agent_name"], lhs: "testing", rhs: "testing2" }
];
const array2 = [
{ lhs: "legacyId", rhs: "id_number" },
{ lhs: "name.short", rhs: "short_name" },
{ lhs: "name.long", rhs: "agent_name" },
{ lhs: "gender", rhs: "gender" },
{ lhs: "dob", rhs: "date_of_birth" }
];
const hashMap = {};
const monValues = [];
for (let i = 0; i < array1.length; i++) {
const currentValue = array1[i].path[0];
hashMap[currentValue] = true;
}
for (let i = 0; i < array2.length; i++) {
const currentValue = array2[i].rhs;
if (hashMap[currentValue]) monValues.push(currentValue);
}
//now monValues contains all of the mon between them. You may want to filter out duplicate matches, depends on your use case.
While it may seem like a lot more code, the time plexity savings are huge as your data gets arbitrarily large by doing it this way. Imagine your data is 100 items long, already an O(n^2) solution would require 10,000 passes to find all of the matches. Conversely with the above solution, it would require 200 passes. These savings in time add up quickly as your data gets larger.
Make a Set
out of the rhs
values in second array and reduce first array and filter paths by checking against the set
const arr1= [ { kind: 'E',
path: [ 'short_name' ],
lhs: 'testing',
rhs: 'testing1' },
{ kind: 'E',
path: [ 'agent_name' ],
lhs: 'testing',
rhs: 'testing2' } ],
arr2= [ { lhs: 'legacyId', rhs: 'id_number' },
{ lhs: 'name.short', rhs: 'short_name' },
{ lhs: 'name.long', rhs: 'agent_name' },
{ lhs: 'gender', rhs: 'gender' },
{ lhs: 'dob', rhs: 'date_of_birth' } ],
arr2Set = new Set(arr2.map(({rhs}) => rhs)),
matches = arr1.reduce((a,{path}) =>[...a, ...path.filter(p => arr2Set.has(p))],[]);
console.log(matches)
本文标签: javascriptFinding Common Values While Looping Over Two ArraysStack Overflow
版权声明:本文标题:javascript - Finding Common Values While Looping Over Two Arrays - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744264610a2597887.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论