How to get the difference between two arrays? - javascript

I have 2 arrays:
arr1 = [[11,12],[11,13],[11,14], [12,13]];
arr2 = [[11,13],[11,14]];
Expected result [[11,12],[12,13]].
How can I get the difference between the two arrays? I use lodash _.difference but it gives me a wrong answer.

You need to use _.differenceWith(), because you need to compare the elements of the sub-arrays. By default, it just tests whether the sub-arrays are the same objects, which they presumably aren't.
result = _.differenceWith(arr1, arr2, _.isEqual);

Using just javascript, and only for this and similar examples
var a1 = [[11,12],[11,13],[11,14], [12,13]];
var a2 = [[11,13],[14,11]];
var a3 = a1.filter(ar1 => !a2.some(ar2 => ar1.every(n1 => ar2.includes(n1))))
console.log(a3); // [[11,12],[12,13]]
There are too many criteria to create a generic solution.
For example is [11,12] the same as [12,11], maybe only references to the same array are the same, (ar1 === ar2) as true. What if there are two identical entries in the same array and one in the other, do you filter one out, or keep it? The number of questions can go on for some time and it gets worse the deeper the nesting and the greater the number of types stored in the array.
var a1 = [[11,12],[11,13],[11,14], [12,13]]
var a2 = [[11,13],[14,11],[12,14]];
a3 = [];
[[a1,a2],[a2,a1]].forEach(a=>{
a3.push(...a[0].filter(
ar1 => !a[1].some(
ar2 => ar1.every(
n1 => ar2.includes(n1)
)
)
))
});
console.log("[["+a3.join("], [")+"]]")

Just a few lines of pure JS is sufficient for this separation (union') job. Besides you should make sure to check both arrays over the other.
var arr1 = [[11,12],[11,13],[11,14],[12,13]],
arr2 = [[11,13],[11,14],[12,14]];
res = arr1.reduceRight((p,c,i,a) => { var fi = p.findIndex(s => c.every(n => s.includes(n)));
return fi !== -1 ? (a.splice(i,1),
p.splice(fi,1),
p)
: p;
},arr2)
.concat(arr1);
console.log(res);

You could do it without lodash. The tip woud be to map subarrays into strings to make comparison easy
var arr1 = [[11,12],[11,13],[11,14], [12,13]];
var arr2 = [[11,13],[11,14],[12,14]];
var res = arr1.concat(arr2).map(x => x.join(",")).filter((x,i,arr) => arr.indexOf(x) === arr.lastIndexOf(x)).map(x => x.split(","));
console.log(res);

Related

How to compare objects of two arrays in JavaScript

I had taken two arrays in JavaScript
arr1 = ["empid","Name"];
arr2 = [{"keyName":"empid" ,"keyValue":"2"}]
And I want to check the value of keyName should be any one element from arr1.
some short-circuits after finding the first match so it doesn't necessarily have to iterate over the whole array of objects. And it also returns a boolean which satisfies your use-case.
const query1 = ['empid','Name'];
const arr1 = [{'keyName':'empid' ,'keyValue':'2'}];
const query2 = ['empid','Name'];
const arr2 = [{'keyName':'empid2' ,'keyValue':'five'}];
const query3 = ['empid','Name', 'test'];
const arr3 = [{'keyName':'test2' ,'keyValue':'five'},{'keyName':'test' ,'keyValue':'five'}];
function found(arr, query) {
return arr.some(obj => {
return query.includes(obj.keyName);
});
}
console.log(found(arr1, query1));
console.log(found(arr2, query2));
console.log(found(arr3, query3));
Use _.isEqual(object, other);
It may help you.

How to combine 2 arrays in a way that 1st element of array1 and 1st element of array2 and so on form a new array

I have 2 arrays. The first contains the years like
[2021,2020,2019,2018,2017]
and the second contains number of occurrence like
[2,3,1,3,3]
I want the new array to look like this
[[2021,2],[2020,3],[2019,1],[2018,3],[2017,3]]
How to do this? Please help!
Thank you in advance.
UPDATE:
const merge = (y, o) => {
const res = [];
y.forEach((year, i) =>
res.push(`${year},${o[i]}`)
);
return res;
};
console.log(merge(allyears,farray))
I tried doing this and it works fine but the new array looks like this
["2021,3","2020,1","2019,2","2018,3","2017,3"]
How to make it look this way
[[2021,2],[2020,3],[2019,1],[2018,3],[2017,3]]
Make sure that the length of 2 arrays is equal
So we have:
const arr1 = [2021,2020,2019,2018,2017];
const arr2 = [2,3,1,3,3];
const combine = arr1.map((value, index) => ([value, arr2[index]]))
console.log(combine)
P/s: There are some other solutions that you can use, but only that one above

Merging two Array one after another Javascript [equal length]

I need to merge two array into one,one after another is there any better way?
for example ,
const arr1 = [1,2,3,4,5];
const arr2 = [a,b,c,d,e];
const resultIWant = [1,a,2,b,3,c,4,d,5,e]
Short and clear if both arrays are same length:
const arr1 = [1,2,3,4,5]
const arr2 = ['a','b','c','d','e']
const res = arr1.flatMap((e, idx) => [e, arr2[idx]])
console.log(res)
This can be done fairly easily using the reduce method. Here is my example below, I iterate through arr1 using reduce() and as I push the current value (c) to the accumulator (a), I also push the value from arr2 of the same index.
In my code below, this looks like a.push(c, arr2[i]) but you could also achieve this using a.push(arr1[i], arr2[i]), using arr1[i] instead of c if you want to keep both push values looking consistent.
const arr1 = [1,2,3,4,5];
const arr2 = ['a','b','c','d','e'];
const result = arr1.reduce((a,c,i) => (a.push(c, arr2[i]), a), []);
console.log(result);

How do I get multiple index on an Array

I am trying to get multiple index positions on an Array for a Boolean value.
I have tried applying a loop using while and for to iterate more then one index position with no success so far.
Here is my code:
let jo = [1,2,3,4,5]
let ji = [1,2,3]
let checker = (arr1,arr2) => {
let falsy = arr1.every(num => arr2.includes(num)) == false ?
arr1.map(falsy => arr2.includes(falsy)) : "tba";
//the block below is the frustrated attempt:
let i = falsy.indexOf(false);
while(i>=0){
return falsy.findIndex(ih => ih == false)
}
}
console.log(checker(jo,ji))
I would like to get the index where false occurs stored in a variable that has iterated over all array so I can use this variable to return just the false values on falsy like this:
return falsy[i] = [4,5]
Then after that I will add more to the first if statement to check both arr1 x arr2 or arr2 x arr1
Thanks in advance!
It looks like you're attempting to get the difference between two arrays. This is a fairly comment use-case for Sets. In this case, your code would look like this:
let jo = [1,2,3,4,5]
let ji = [1,2,3]
const checker = (arr1, arr2) => {
return new Set(arr1.filter(x => !new Set(arr2).has(x)))
}
console.log(checker(jo, ji)); // {4, 5}
If you wanted to get the indexes of the differences, you would need to apply a map to the result of the new Set like so:
const checker = (arr1, arr2) => {
const difference = new Set(arr1.filter(x => !new Set(arr2).has(x)));
return Array.from(difference).map(value => arr1.indexOf(v));
}

2-dimensional arrays in ES6

Long story short, i'm looking for a way to create and fill 2D arrays using ES6, in an effort to avoid for loops. The created array should contain all 0s. I've tried many different approaches so i cant post all of them.
var [r, c] = [5, 5];
var m = Array(r).fill(Array(c).fill(0));
This works but it creates a bunch of instances of the same array, and adding slice Array(r).fill(Array(c).fill(0).slice()); doesn't help either.
I also tried creating the empty arrays and then looping trough them but that's a whole different problem, you apparently can't forEach() or map() an empty array, and i couldn't even loop through a filled one efficiently.
Am i missing something here? Are a whole lot of for loops the best way to approach this? It looks really messy and overly long. Any help appreciated.
Doing this worked for me:
var [r, c] = [5, 5];
var m = Array(r).fill().map(()=>Array(c).fill(0));
Basically just filling it with a dummy value so you can map over it
You could use Array.from that takes a callback function and inside return arrays with 0's using fill method.
const arr = Array.from(Array(2), () => Array(5).fill(0))
console.log(arr)
Or you could just create array where each element is number of elements in sub-array and then use map and fill methods.
const arr = [5, 5].map(e => Array(e).fill(0))
console.log(arr)
For those needing the same thing but with undefined as each value this also works.
const x = 100;
const y = 100;
const grid = [...new Array(x)].map(() => [...new Array(y)]);
To fill the array simply map the inner value.
This will make an array filled with 0 for each value.
const x = 100;
const y = 100;
const grid = [...new Array(10)].map(() => [...new Array(10)].map(() => 0));
const nthArray = (n) => Array.from(Array(n), () => Array(5).fill(0))
const arr = nthArray(3);
console.log(arr);

Categories

Resources