'Need to compare two arrays with a callback and return an object in Javascript
Construct a function objOfMatches that accepts two arrays and a callback. objOfMatches will build an object and return it. To build the object, objOfMatches will test each element of the first array using the callback to see if the output matches the corresponding element (by index) of the second array. If there is a match, the element from the first array becomes a key in an object, and the element from the second array becomes the corresponding value. I got this so far:
const objOfMatches = (arr1,arr2,call) => {
let result = {};
for(let i = 0; i < arr1.length; i++){
//Don't know how to check each element using the callback
}
return result
}
const arr1 = ['hi', 'howdy', 'bye', 'later', 'hello'];
const arr2 = ['HI', 'Howdy', 'BYE', 'later', 'HELLO'];
function uppercaser(str) { return str.toUpperCase(); }
console.log(objOfMatches(arr1, arr2, uppercaser));
// should log: { hi: 'HI', bye: 'BYE', hello: 'HELLO' }
Solution 1:[1]
Try this:
const objOfMatches = (arr1,arr2,call) => {
let result = {};
for(let i = 0; i < arr1.length; i++){
let upper = call(arr1[i]);
if(arr2[i] && upper == arr2[i])
result[arr1[i]] = arr2[i];
}
return result
}
const arr1 = ['hi', 'howdy', 'bye', 'later', 'hello'];
const arr2 = ['HI', 'Howdy', 'BYE', 'later', 'HELLO'];
function uppercaser(str) { return str.toUpperCase(); }
console.log(objOfMatches(arr1, arr2, uppercaser));
Solution 2:[2]
Here is a functional programming solution:
const objOfMatches = (arr1, arr2, call) =>
Object.fromEntries(arr1.map((v,i) => [v, arr2[i]])
.filter(([a,b]) => call(a) === b));
const arr1 = ['hi', 'howdy', 'bye', 'later', 'hello'];
const arr2 = ['HI', 'Howdy', 'BYE', 'later', 'HELLO'];
const uppercaser = str => str.toUpperCase();
console.log(objOfMatches(arr1, arr2, uppercaser));
Explanation
objOfMatches is a function defined with arrow syntax, where the part that follows the (first) => is the expression that determines the function's return value. The same arrow syntax is used for all other functions in this solution as well.
First the two arrays are "zipped" into one array of pairs, using arr1.map((v,i) => [v, arr2[i]]). This takes every value v from arr1 and pairs it with the value from arr2 that sits at the same index. So for the example input, this produces the following:
[
['hi', 'HI'],
['howdy', 'Howdy'],
['bye', 'BYE'],
['later', 'later'],
['hello', 'HELLO']
]
Then .filter is called on this intermediate result, only keeping the pairs [a,b] where call(a) === b. So then we have:
[
['hi', 'HI'],
['bye', 'BYE'],
['hello', 'HELLO']
]
Finally, this is passed as argument to the Object.fromEntries function, which turns an array of key/value pairs into a plain object having those keys and values.
Solution 3:[3]
const objOfMatches = (arr1,arr2,call) => {
let result = {};
arr1.forEach((item, i) => {
if(call(item) === arr2[i]) {
result[item] = arr2[i]
}
})
return result;
}
const arr1 = ['hi', 'howdy', 'bye', 'later', 'hello'];
const arr2 = ['HI', 'Howdy', 'BYE', 'later', 'HELLO'];
function uppercaser(str) { return str.toUpperCase(); }
console.log(objOfMatches(arr1, arr2, uppercaser));
// should log: { hi: 'HI', bye: 'BYE', hello: 'HELLO' }
Solution 4:[4]
const objOfMatches = (array1, array2, callback) => array1.reduce((prev, curr) => {
if (callback(curr) === prev.compareAgainst[0]) {
prev.obj[curr] = prev.compareAgainst[0];
}
prev.compareAgainst = prev.compareAgainst.slice(1);
return prev;
}, {obj: {}, compareAgainst: array2}).obj;
console.log(objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'], ['HI', 'Howdy', 'BYE', 'LATER', 'hello'], (str) => str.toUpperCase()));
// should log: { hi: 'HI', bye: 'BYE', later: 'LATER' }
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Majed Badawi |
| Solution 2 | |
| Solution 3 | |
| Solution 4 | Ashutosh Bhadoria |
