Lodash is a very useful utility library that lets us work with objects and arrays easily.
However, now that the JavaScript standard library is catching up to libraries such as Lodash, we can implement many of the functions in simple ways.
In this article, we’ll look at some methods to get the symmetric difference and zipping arrays.
xorBy
The xorBy
method returns the symmetric difference of multiple arrays, which is an array without the entries that appear in all the arrays.
It does that by first running an iteratee
function before doing the comparison. The iteratee
function takes one argument to map a given entry to something else.
We can do that as follows:
const xorBy = (iteratee, ...arrs) => {
const symDiff = [];
for (const arr of arrs) {
for (const a of arr) {
const inAllArrays = arrs.every(arr => arr.map(iteratee).includes(iteratee(a)));
if (!inAllArrays) {
symDiff.push(a);
}
}
}
return symDiff;
}
In the code above, we used the rest operator to spread the arrays argument into an array of arrays.
Then we used the every
method that’s in plain JavaScript to see if an entry is in all the arrays in our for...of
loop.
When doing the comparison, we call map
first with the iteratee
function, then we also call iteratee
when calling includes
so that we’re comparing the mapped values instead of the original values.
Then if it’s not in the original array, then we put it in the symDiff
array.
When we call it as follows:
const result = xorBy(Math.floor, [2.1, 1], [2.2, 3])
We get that result
is [1, 3]
because we mapped the values with Math.floor
before comparing, so 2.1 and 2.2 are considered the same and are in all the arrays.
xorWith
xorWith
is similar to xorBy
in that, it runs a function. The difference is that the function is used to compare the values instead of mapping the values before comparing the items.
We can implement it similar to xorBy
as follows:
const xorWith = (comparator, ...arrs) => {
const symDiff = [];
for (const arr of arrs) {
for (const a of arr) {
const inAllArrays = arrs.every(arr => arr.findIndex(b => comparator(a, b)) >= 0);
if (!inAllArrays) {
symDiff.push(a);
}
}
}
return symDiff;
}
In the code above, we used the every
method like we did with xorBy
, but we called findIndex
with comparator
inside to compare the values to determine if they’re in all the arrays.
If they’re not then we push them into the symDiff
array. In the end, we return it.
Then when we call it as follows:
const result = xorWith((a, b) => Math.floor(a) === Math.floor(b), [2.1, 1], [2.2, 3])
We get tat result
is:
[
1,
3
]
zip
The Lodash zip
method groups elements, with the first elements of each array in the first array, the second element of each array in the second array, and so on.
We can do that we for
loops as follows:
const zip = (...arrs) => {
let zipped = [];
for (let i = 0; i < arrs[0].length; i++) {
if (!Array.isArray(zipped[i])) {
zipped[i] = [];
}
for (const arr of arrs) {
zipped[i].push(arr[i]);
}
}
return zipped;
}
In the code above, we used the rest operator to spread the arrs
argument into an array of arrays.
Then we loop through the items with a for
loop and inside it, we check that if zipped[i]
isn’t an array, then we create an array.
Once we did that we loop through the arrays in arrs
with the for...of
loop and get the array entry in the position i
of each array and push it into the arrays in zipped
array in the same position.
Then when we call zip
as follows:
const result = zip(['a', 'b'], [1, 2], [true, false])
We see that result
is:
[
[
"a",
1,
true
],
[
"b",
2,
false
]
]
Conclusion
We can get the symmetric difference in different ways with Lodash either by mapping the values with an iteratee
function or by comparing them with the conparator
function.
To zip an array of arrays, we create a new array by first creating a new array of arrays, then we push each entry of the original nested array in the given position into the new nested array in the same position.
Then we return that array.