find an array in another array in javascript [duplicate] - javascript

This question already has answers here:
How to compare arrays in JavaScript?
(55 answers)
Closed 4 years ago.
Is there any function in JS to check "If an array exists in a larger array?"
I tried array.includes() and array.indexOf() but they didn't work for me...
for example I except a true return value here:
parent = [[a,b],[c,d],[e,f]]
child = [c,d]

Your includes fails because you're trying to match reference. A well detailed explanation you can see on this answer https://stackoverflow.com/a/54363784/9624435
You can use filter and every
let parent = [['a','b'],['c','d'],['e','f']];
let child = ['c','d'];
let result = parent.filter(arr => arr.every(v => child.includes(v)));
console.log(result);

Let's focus on why .includes fail.
Array.includes uses following function to check equality:
function sameValueZero(x, y) {
return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
}
Since you have arrays as element, they are copied using references, so you are checking references of arrays instead. Hence it fails.
Following is a sample:
const item1 = ['a', 'b'];
const item2 = ['c', 'd'];
const item3 = ['e', 'f']
const parent = [item1, item2, item3]
const child = item3;
console.log(parent.includes(child))
Hence, you will have to go deeper and check individual values.
References:
Why [] == [] is false in JavaScript?
Array.includes polyfill
How to compare arrays in JavaScript?: as rightly suggested by #Chris G

Related

Javascript includes() failing [duplicate]

This question already has answers here:
Check if an array includes an array in javascript
(3 answers)
Why doesn't equality check work with arrays [duplicate]
(6 answers)
Closed 1 year ago.
Why are the last two console.logs showing false?
const a = 'one';
const b = 'two';
const myArray = [[ 'one', 'two'], ['three', 'four'], ['five', 'six']];
console.log([a, b]);
console.log(myArray[0]);
console.log(myArray.includes([a, b]));
console.log(myArray[0] === [a, b]);
in JavaScript arrays and objects are compared by reference and not by value.
One solution I suggest is to use JSON.stringify()
a = ["a", "b"]
b = ["a", "b"]
console.log(JSON.stringify(a) == JSON.stringify(a)) // return true
Array.prototype.includes() and triple equal operator === work with references, they don't compare the elements of the arrays, they compare the array references themselves:
console.log([] === []); // false
const a = [];
const b = a;
console.log(a === b); // true
You could first convert the array (object) to a string using JSON.stringify(), then compare the string:
const a = 'one';
const b = 'two';
const myArray = [
['one', 'two'],
['three', 'four'],
['five', 'six']
];
console.log(JSON.stringify(myArray[0]) === JSON.stringify([a, b]));
You can also run through the separate values using every() and compare them like this:
const a = 'one';
const b = 'two';
const myArray = [[ 'one', 'two'], ['three', 'four'], ['five', 'six']];
const isequal = [a, b].length === myArray[0].length && [a, b].every((value, i) => value === myArray[0][i]);
console.log(isequal);
Arrays in JavaScript are Objects and Objects comparison will always return false if the referenced objects aren't the same.
If you want to compare arrays you have to write a function for this or use isEqual func from lodash
https://lodash.com/docs/4.17.15#isEqual

Best way to check if some coordinate is contained in an array (JavaScript)

When dealing with arrays of coordinates, seen as arrays of length 2, it is necessary to check if some coordinate is contained in that array. However, JavaScript cannot really do that directly (here I use that ES2016 method Array.includes, but with the more classical Array.indexOf the same issue appears):
const a = [[1,2],[5,6]];
const find = a.includes([5,6]);
console.log(find);
This returns false. This has always bothered me. Can someone explain to me why it returns false? To solve this issue, I usually define a helper function:
function hasElement(arr,el) {
return arr.some(x => x[0] === el[0] && x[1] === el[1])
}
The inner condition here could also be replaced by x.toString() === el.toString(). Then in the example above hasElement(a,[5,6]) returns true.
Is there a more elegant way to check the inclusion, preferably without writing helper functions?
You can use JSON.stringify method to convert the javascript object or value to a JSON string and then do the same for the array you want to search and just check if the main array includes the array you want to find.
const a = [[1,2],[5,6]], array = [5,6];
const find = JSON.stringify(a).includes(JSON.stringify(array));
console.log(find);
The reason is that in JavaScript, arrays are just objects and cannot be compared like values. Two object instances will never be equal, so even though they look identical to the eye, they are completely different objects and therefore will always be unequal. See:
console.log([5, 6] === [5, 6]) // false
The JavaScript Array class is a global object that is used in the construction of arrays; which are high-level, list-like objects.
You can try with find and destructure to simplify.
const a = [
[1, 2],
[5, 6]
];
const target = [5, 6];
// Method 1
const find = a.find(x => x.every(y => target.includes(y)));
// Method 2
const [xt, yt] = target;
const find2 = a.find(([x, y]) => xt === x && yt === y);
console.log(find, find2);
Referring back to Siva K V's answer. If you want to find the index of the first occurrence in the array where this is true, just replace find with findIndex (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex)
const a = [
[1, 2],
[5, 6]
];
const target = [5, 6];
// Method 1
const find = a.findIndex(x => x.every(y => target.includes(y)));
// Method 2
const [xt, yt] = target;
const find2 = a.findIndex(([x, y]) => xt === x && yt === y);
console.log(find, find2);

Unusual if/else behaviour [duplicate]

This question already has answers here:
How to compare arrays in JavaScript?
(55 answers)
Closed 5 years ago.
I have an array of two nested arrays.
var array = [ [a,b,c], [a,b,c] ]
Despite the array elements being identical, the following code returns true:
if (array[0] !== array[1]) {
console.log(array[0])
console.log(array[1])
}
// [a,b,c]
// [a,b,c]
And the following code returns false:
if (array[0] === array[1]) {
console.log(array[0])
console.log(array[1])
}
It seems to be comparing the indices instead of the elements.
What is going on here?
Sometimes I will be comparing 3 or possibly even 4 nested arrays to each other. For instance, if ( array[0] === array[1] || array[0] === array[2] || array[1] === array[2] ) // do this. Notably, a and c will always be references to actual HTML elements, whereas b will be a number. Is there not a simple way to accomplish this nowadays?
You are comparing object references, not object values. The pointers to memory are different, and as a result the comparison is false.
Here is a simple example using html elements in the arrays.
var a1 = document.querySelectorAll('div');
var a2 = document.querySelectorAll('div');
var a3 = document.querySelectorAll('div');
var array = [Array.from(a1),Array.from(a2),Array.from(a3)];
console.log(array[0].every((v,i) => array.slice(1).every(ai => v == ai[i])));
<div>1</div><div>2</div><div>3</div>

Why is this test failing? Array should equal [] [duplicate]

This question already has answers here:
chai test array equality doesn't work as expected
(7 answers)
Closed 6 years ago.
My test, below the alerts var is an empty array [] however this throws an error.
it('FeedFactory alerts array is filled', function() {
var alerts = FeedFactory.returnAlerts();
console.log('alerts',alerts);
expect(alerts).to.equal([]);
});
Here is the test log when I comment out the last expect(alerts).to.equal([]); line.
Code from my Factory
var alerts = [];
var feedFactory = {
alerts : alerts,
getFeed : getFeed,
returnAlerts : returnAlerts,
saveFilters : saveFilters,
getFilters : getFilters
};
function returnAlerts() {
return alerts;
}
Because [] !== [] && [] != []. JS objects are not loosely or strictly equal to one another, so expect([]).to.equal([]) will always fail.
You should use a deeper form of equality, such as deep (or its confusing shorthand, eql) or members:
expect([1, 2, 3]).to.deep.equal([1, 2, 3])
expect([1, 2, 3]).to.include.members([1, 2])
Two empty arrays are not equal to each other because each has a different reference, since all objects, (and arrays for that matter) are referenced and not copied. The checking for equality on objects are checking on reference and not internal content
hance:
var a = [];
var b = [];
console.log(a == b) //false
i would use the length of the alerts array inorder to test if its an empty array. by writing:
expect(alerts.length).to.equal(0);
in order to check the content of the array to equal another content of another array, you must use deep checking, which checks for each value of the array to equal the one in the other array (quite expensive).

How to check identical array in most efficient way? [duplicate]

This question already has answers here:
How to check if two arrays are equal with JavaScript? [duplicate]
(16 answers)
Closed 10 years ago.
I want to check if the two arrays are identical
(not content wise, but in exact order).
For example:
array1 = [1,2,3,4,5]
array2 = [1,2,3,4,5]
array3 = [3,5,1,2,4]
Array 1 and 2 are identical but 3 is not.
Is there a good way to do this in JavaScript?
So, what's wrong with checking each element iteratively?
function arraysEqual(arr1, arr2) {
if(arr1.length !== arr2.length)
return false;
for(var i = arr1.length; i--;) {
if(arr1[i] !== arr2[i])
return false;
}
return true;
}
You could compare String representations so:
array1.toString() == array2.toString()
array1.toString() !== array3.toString()
but that would also make
array4 = ['1',2,3,4,5]
equal to array1 if that matters to you

Categories