This question already has answers here:
How to compare arrays in JavaScript?
(55 answers)
How to detect array equality in JavaScript?
(4 answers)
Closed 6 years ago.
How do I check for equality between the elements of two arrays without using external libraries (and preferably using ES5)?
I want to check for equality between them without caring about the order of the elements. So the two arrays [1,2,3] and [2,3,1] are equal in my situation.
I guess I should write a function
function isEqual(arr1, arr2) {
arr1.forEach(el => {
if (arr2.indexOf(el) === -1) {
return false;
}
});
arr2.forEach(el => {
if (arr1.indexOf(el) === -1) {
return false;
}
});
return true;
}
You can use JSON.stringify and Array#sort methods. Sort both the arrays ang compare them after converting to JSON string.
function isEqual(arr1, arr2) {
return JSON.stringify(arr1.sort()) === JSON.stringify(arr2.sort());
}
console.log(isEqual([1, 2, 3], [2, 3, 1]));
console.log(isEqual([1, 2, 3], [2, 4, 1]));
console.log(isEqual([1, 2, 3, 3], [2, 3, 1]));
console.log(isEqual([1, 2, 3, 3], [2, 4, 1, 1]));
Or instead of JSON.stringify you can also use Array#join method( Suggested by #JonCarter ) which makes it little more simple.
function isEqual(arr1, arr2) {
return arr1.sort().join() === arr2.sort().join();
}
console.log(isEqual([1, 2, 3], [2, 3, 1]));
console.log(isEqual([1, 2, 3], [2, 4, 1]));
console.log(isEqual([1, 2, 3, 3], [2, 3, 1]));
console.log(isEqual([1, 2, 3, 3], [2, 4, 1, 1]));
You could use Array#every to assert the values are equal. This is very rudimentary though as uses a strict equality check which has its limitations. But this shows the rough framework for a iterating over the array.
NOTE: Since arrays are index based lists it is assumed that for them to be equal they would need to have equal values at the same index.
var arr1 = [1,2,3,4];
var arr2 = [1,2,3,4];
var arr3 = [1,2,4];
var arr4 = [1,2,2,4];
function isArrEql(a1, a2) {
return a1.length === a2.length && a1.every(function(v, i) {
return v === a2[i];
});
}
console.log('arr1, arr2: ', isArrEql(arr1, arr2));
console.log('arr1, arr2: ', isArrEql(arr1, arr3));
console.log('arr1, arr2: ', isArrEql(arr1, arr4));
Related
This question already has answers here:
Merge/flatten an array of arrays
(84 answers)
Closed last year.
I have an argument that passes me a 2D array and I want to get the numbers from that array and put them on a normal array.
The argument passed to me = ([1, 3, 2], [5, 2, 1, 4], [2, 1])
What I want to do = [1, 3, 2, 5, 2, 1, 4, 2, 1]
Thanks in advance, I think I'm having a brain fart over here!
You can use the flat method of Array!
const arr = [[1, 2, 3], [4, 5, 6]]
console.log(arr.flat())
// [1, 2, 3, 4, 5, 6]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
Iterate the array and add all data in new array with concat() method.
var arr = [[1, 3, 2], [5, 2, 1, 4], [2, 1]];
var newArr = [];
for(var i = 0; i < arr.length; i++)
{
newArr = newArr.concat(arr[i]);
}
console.log(newArr);
You can use array flat method to convert 2d array to 1d array
const arr = [
[1,2,3],
[4,5,6]
].flat(1); //flat(depth:Number)
console.log(arr);
// [1,2,3,4,5,6]
The .length property on an array will return the number of elements in the array. For example, the array below contains 2 elements:
[1, [2, 3]] // 2 elements, number 1 and array [2, 3]
Suppose we instead wanted to know the total number of non-nested items in the nested array. In the above case, [1, [2, 3]] contains 3 non-nested items, 1, 2 and 3.
Examples
getLength([1, [2, 3]]) ➞ 3
getLength([1, [2, [3, 4]]]) ➞ 4
getLength([1, [2, [3, [4, [5, 6]]]]]) ➞ 6
You can flatten the array using .flat(Infinity) and then get the length. Using .flat() with an argument of Infinity will concatenate all the elements from the nested array into the one outer array, allowing you to count the number of elements:
const getLength = arr => arr.flat(Infinity).length;
console.log(getLength([1, [2, 3]])) // ➞ 3
console.log(getLength([1, [2, [3, 4]]])) // ➞ 4
console.log(getLength([1, [2, [3, [4, [5, 6]]]]])) // ➞ 6
You can use reduce on each array it'll find like this :
function getLength(arr){
return arr.reduce(function fn(acc, item) {
if(Array.isArray(item)) return item.reduce(fn);
return acc + 1;
}, 0);
}
console.log(getLength([1, [2, 3]]))
console.log(getLength([1, [2, [3, 4]]]))
console.log(getLength([1, [2, [3, [4, [5, 6]]]]]))
Recursively count the elements that you don't recurse into:
function getLength(a) {
let count = 0;
for (const value of a) {
if (Array.isArray(value)) {
// Recurse
count += getLength(value);
} else {
// Count
++count;
}
}
return count;
}
Live Example:
function getLength(a) {
let count = 0;
for (const value of a) {
if (Array.isArray(value)) {
count += getLength(value);
} else {
++count;
}
}
return count;
}
console.log(getLength([1, [2, 3]]));
console.log(getLength([1, [2, [3, 4]]]));
console.log(getLength([1, [2, [3, [4, [5, 6]]]]]));
You could just add the lengths for nested array or one.
function getLength(array) {
let count = 0;
for (const item of array) count += !Array.isArray(item) || getLength(item);
return count;
}
console.log(getLength([1, [2, 3]]));
console.log(getLength([1, [2, [3, 4]]]));
console.log(getLength([1, [2, [3, [4, [5, 6]]]]]));
So here's the proposed problem.
Compare two arrays and return a new array with any items not found in both of the original arrays.
Here's what I have so far.
function diff(arr1, arr2) {
for (var a in arr1) {
for (var b in arr2) {
if (arr1[a] == arr2[b]){
arr2.splice(b,1);
}
}
}
return arr2;
}
diff([1, 2, 3, 5], [1, 2, 3, 4, 5]);
This code basically just compares each value of the first array with the second one. If a match is found it then removes the item using the splice function.
This works great for arrays that are one dimensional but how can I get it to work for multidimensional arrays such as:
diff([1, 2, 3, 5], [1, [2, 3], [4, 5]]);
What if these arrays are not just two dimensions but any number of dimensions. I should be able to iterate through every element of every array no matter they are set up.
With lodash you can do this :
var a = [1, 2, 3, 5, 7], b = [1, [2, 3], [4, 5, [7]]];
var result = _.filter(_.flattenDeep(b), function(item){
return a.indexOf(item) === -1;
});
console.log(result);
$("body").append(JSON.stringify(result))
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js"></script>
<body></body>
Below are several stabs at removing 3 from the array [8,2,3,4] using lodash. The elegant syntax for removing an object from an array of objects makes me wonder if I just haven't figured out the right approach here.
> _.remove([8,2,3,4], 3)
[]
> x = [8,2,3,4]
[8, 2, 3, 4]
> _.remove(x, 3)
[]
> x
[8, 2, 3, 4]
> _.remove(x, {3: true})
[]
> x
[8, 2, 3, 4]
> _.remove(x, [3])
[]
> x
[8, 2, 3, 4]
> _.remove(x, function(val) { return val === 3; });
[3]
> x
[8, 2, 4]
Is there another way to remove a matching element from an array that would be similar to _.remove(arrayOfObjs, {id:3})
Yes, but not using remove. You can instead use pull to remove values from an array:
Removes all provided values from array using SameValueZero for equality comparisons.
// pull modifies its argument:
x = [8, 2, 3, 4]
_.pull(x, 3)
x // => [8, 2, 4]
// pull also returns the modified array:
y = _.pull([1, 2, 3, 4, 5], 2, 3) // => [1, 4, 5]
I am now writing a javascript to filter out arrays that contains a specific sub-array. Of course I can write the function by myself, but I am just curious if there are already some built-in function in javascript or other javascript library to do that, or if there are easy way to do that with just a few lines.
I found that I can use underscore.js if all the elements in the sub-array is unique. There is a intersection function and I can check the lenght after intersection to see if the length are correct. However, that function fails if there are repeated values in the sub-array.
For example,
_.intersection([1, 2, 3, 4, 5], [2, 1]);
This will return [1, 2] and by checking the length I will know this array contains the sub-array.
However, when there are repeated values in the sub-array,
_.intersection([1, 1, 2, 3, 4, 7, 10], [1, 1, 2]);
_.intersection([1, 2, 3, 4], [1, 1, 2]);
Both will return [1, 2] and the cases cannot be distinguished.
Is there other pre-built function I can use or is there a easy way to do the job within a few lines?
Try this:
function contains(a, b) {
// sort arguments
if(a.length < b.length) {
var temp = a;
a = b;
b = temp;
}
// copy array
a = a.slice();
return b.every(function(elm) {
var index = a.indexOf(elm);
if(index !== -1) {
// remove the found element
a.splice(index, 1);
return true;
}
return false;
});
}
console.log(contains([1, 1, 2], [1, 2, 3, 4, 7, 10])); // logs false
console.log(contains([1, 1, 2], [1, 1, 2, 3, 4, 7, 10])); // logs true
console.log(contains([1, 2, 3, 4, 7, 10], [1, 1, 2])); // logs false
console.log(contains([1, 1, 2, 3, 4, 7, 10], [1, 1, 2])); // logs true
Here is the demo