How to Compare two Arrays are Equal using Javascript? [duplicate] - javascript

This question already has answers here:
How to compare arrays in JavaScript?
(55 answers)
Closed 3 years ago.
I want position of the array is to be also same and value also same.
var array1 = [4,8,9,10];
var array2 = [4,8,9,10];
I tried like this
var array3 = array1 === array2 // returns false

You could use Array.prototype.every().(A polyfill is needed for IE < 9 and other old browsers.)
var array1 = [4,8,9,10];
var array2 = [4,8,9,10];
var is_same = (array1.length == array2.length) && array1.every(function(element, index) {
return element === array2[index];
});
THE WORKING DEMO.

A less robust approach, but it works.
a = [2, 4, 5].toString();
b = [2, 4, 5].toString();
console.log(a===b);

var array3 = array1 === array2
That will compare whether array1 and array2 are the same array object in memory, which is not what you want.
In order to do what you want, you'll need to check whether the two arrays have the same length, and that each member in each index is identical.
Assuming your array is filled with primitives—numbers and or strings—something like this should do
function arraysAreIdentical(arr1, arr2){
if (arr1.length !== arr2.length) return false;
for (var i = 0, len = arr1.length; i < len; i++){
if (arr1[i] !== arr2[i]){
return false;
}
}
return true;
}

A more modern version:
function arraysEqual(a, b) {
a = Array.isArray(a) ? a : [];
b = Array.isArray(b) ? b : [];
return a.length === b.length && a.every((el, ix) => el === b[ix]);
}
Coercing non-array arguments to empty arrays stops a.every() from exploding.
If you just want to see if the arrays have the same set of elements then you can use Array.includes():
function arraysContainSame(a, b) {
a = Array.isArray(a) ? a : [];
b = Array.isArray(b) ? b : [];
return a.length === b.length && a.every(el => b.includes(el));
}

You could try this simple approach
var array1 = [4,8,9,10];
var array2 = [4,8,9,10];
console.log(array1.join('|'));
console.log(array2.join('|'));
if (array1.join('|') === array2.join('|')) {
console.log('The arrays are equal.');
} else {
console.log('The arrays are NOT equal.');
}
array1 = [[1,2],[3,4],[5,6],[7,8]];
array2 = [[1,2],[3,4],[5,6],[7,8]];
console.log(array1.join('|'));
console.log(array2.join('|'));
if (array1.join('|') === array2.join('|')) {
console.log('The arrays are equal.');
} else {
console.log('The arrays are NOT equal.');
}
If the position of the values are not important you could sort the arrays first.
if (array1.sort().join('|') === array2.sort().join('|')) {
console.log('The arrays are equal.');
} else {
console.log('The arrays are NOT equal.');
}

If you comparing 2 arrays but values not in same index, then try this
var array1=[1,2,3,4]
var array2=[1,4,3,2]
var is_equal = array1.length==array2.length && array1.every(function(v,i) { return ($.inArray(v,array2) != -1)})
console.log(is_equal)

Use lodash.
In ES6 syntax:
import isEqual from 'lodash/isEqual';
let equal = isEqual([1,2], [1,2]); // true
Or previous js versions:
var isEqual = require('lodash/isEqual');
var equal = isEqual([1,2], [1,2]); // true

Here goes the code. Which is able to compare arrays by any position.
var array1 = [4,8,10,9];
var array2 = [10,8,9,4];
var is_same = array1.length == array2.length && array1.every(function(element, index) {
//return element === array2[index];
if(array2.indexOf(element)>-1){
return element = array2[array2.indexOf(element)];
}
});
console.log(is_same);

function isEqual(a) {
if (arrayData.length > 0) {
for (var i in arrayData) {
if (JSON.stringify(arrayData[i]) === JSON.stringify(a)) {
alert("Ya existe un registro con esta informacion");
return false;
}
}
}
}
Check this example

Try doing like this: array1.compare(array2)=true
Array.prototype.compare = function (array) {
// if the other array is a falsy value, return
if (!array)
return false;
// compare lengths - can save a lot of time
if (this.length != array.length)
return false;
for (var i = 0, l=this.length; i < l; i++) {
// Check if we have nested arrays
if (this[i] instanceof Array && array[i] instanceof Array) {
// recurse into the nested arrays
if (!this[i].compare(array[i]))
return false;
}
else if (this[i] != array[i]) {
// Warning - two different object instances will never be equal: {x:20} != {x:20}
return false;
}
}
return true;
}

Related

How to return object formed from two properties, one property (name) from one array and second property (value) from second array

I am suppose to write a method in which I have two parameters (two arrays), and method should return an object that has as many properties as one of the arrays has, property name should be given from one array, and value property from second array.
Thanks for the help in advance. :D
function reaction(array1, array2) {
if (array1.lenght !== array2.lenght || array1.lenght === 0 || array2.lenght === 0) {
return null;
}
let obj = {};
array1.forEach((e1, e2) => { obj[e1] = array2[e2] })
return obj;
};
console.log(reaction(codes, names))
You could use Array.reduce() to create the resulting object from the input arrays.
This creates an object with a key named for each element in the first array, with a value from the second.
function reaction(array1, array2) {
if (array1.length !== array2.length || array1.length === 0 || array2.length === 0) {
return null;
}
return array1.reduce((acc, key, idx) => {
acc[key] = array2[idx];
return acc;
}, {});
}
// Some examples to illustrate...
console.log(reaction(['length', 'width', 'height'], [3, 4, 5]))
console.log(reaction(['age', 'income'], [42, 55000]))
You could also use a simple for loop to achieve the same result, again using array1 as keys and those in array2 as values.
function reaction(array1, array2) {
if (array1.length !== array2.length || array1.length === 0 || array2.length === 0) {
return null;
}
let obj = {};
for(let i = 0; i < array1.length; i++) {
obj[array1[i]] = array2[i];
}
return obj;
}
// Some examples to illustrate...
console.log(reaction(['length', 'width', 'height'], [3, 4, 5]))
console.log(reaction(['age', 'income'], [42, 55000]))

Determine whether an array contains anything other than a specified value in javascript?

I'm trying to write a function that can check whether a specified value exists in an array and also whether a value other than what is specified exists in an array. I'm looking for a modern solution, no backwards compatibility is required.
          
For example:
const array = [1,1,1,2,3];
// this checks whether a value exists
const valExists = (array, value) => array.includes(value);
valExists(array,1); // returns true
Now, how do I check whether anything other than 1 exists?
I've tried manipulating the function parameter value e.g:
valExists(array, !1); // returns false, i want 'true'
Solution
I've integrated the solution provided by my accepted answer as follows:
const array = [1,1,1,2,3];
const array2 = [1,1,1,1,1];
//this checks whether a value exists and also whether it is unique
function existUnique(array, value) { let a = array.includes(value); let b = array.every( e => e === value ); console.log(`${a}: ${b}`);};
The results are:
existUnique(array, 1); // true: false
existUnique(array2, 1); // true: true
You can use Array.prototype.every()
The every() method tests whether all elements in the array pass the test implemented by the provided function
const array = [1,1,1,2,3];
const array2 = [1,1,1,1,1];
console.log(array.every(x => x === 1)); //false
console.log(array2.every(x => x === 1)); //true
You could use some() in combination of your valExists:
const arr1 = [1, 1, 1, 1, 1];
const arr2 = [1, 2, 2, 1, 3];
const arr3 = [2, 2, 2, 5, 3];
const valExists = (array, value) => array.includes(value);
const valIsUnique = (array, value) =>
valExists(array, value) && !array.some(v => v !== value);
console.log('arr1', valIsUnique(arr1, 1));
console.log('arr2', valIsUnique(arr2, 1));
console.log('arr3', valIsUnique(arr3, 1));
But the fastest (depending on the input) might actually be creating a Set from it:
const arr1 = [1, 1, 1, 1, 1];
const arr2 = [1, 2, 2, 1, 3];
const arr3 = [2, 2, 2, 5, 3];
const valIsUnique = (array, value) => {
const set = new Set(array);
return set.size === 1 && set.has(value);
};
console.log('arr1', valIsUnique(arr1, 1));
console.log('arr2', valIsUnique(arr2, 1));
console.log('arr3', valIsUnique(arr3, 1));
I would use Array.prototype.some() for this, the below will return true if 1 appears anywhere inside your array object.
The some() method tests whether at least one element in the array passes the test implemented by the provided function.
const array = [1,1,1,2,3];
const hasOne = function(element) {
return element === 1;
};
console.log(array.some(hasOne)); // true
OR anything other than 1 exists.
const array = [1,1,1,2,3];
const noOne = function(element) {
return element !== 1;
};
console.log(array.some(noOne)); // true
You return an object with two keys containsValue & containOthers which will have boolean . containsValue value will be determined by use of includes & containOthers value can be determined using filter and checking the length of the returned array
const array = [1, 1, 1, 2, 3];
function valExists(arr, val) {
return {
containsValue: arr.includes(val),
containOthers: arr.filter(item => item !== val).length > 0 ? true : false
}
}
console.log(valExists(array, 1));
you just need to check the length of the array, if the array includes the value and the length of the array is more than 1 it means that the value is on the array and exists something else on the array too :)
You can use filter and compare the length of original and filtered array
const array = [1,1,1,2,3];
const array1 = [1,1,1,1,1]
console.log(array.filter(a=>a===1).length===array.length)
console.log(array1.filter(a=>a===1).length===array1.length)
It depends on your input. If your input include only primitive value, use can use some methods like Array.prototype.some() or Array.prototype.includes(). Other people already gave you the answer using them.
My addition is in case your array contain literal object or array, those methods will not work as expect. In this case you will need to write your own test in case of array and object. Read this answer
Bonus: This is my solution for compare two array/object
// Own way to compare two array
// Compare only the object itself and all element inside.
// Not compare constructor or prototypes of it
function checkObjectInsideOtherObject(child, parent) {
let parentArray = convertObjectToArrayOfSinglePropertyObject(parent);
let childArray = convertObjectToArrayOfSinglePropertyObject(child);
let arr = arrayDifference(childArray, parentArray);
return arr.length === 0;
}
// ***Convert an object to an array of single property objects
function convertObjectToArrayOfSinglePropertyObject(obj) {
let array = [];
for (let element in obj) {
array.push({ [element]: obj[element] });
}
return array;
}
//***Compare two object that have only one property each
function compareSinglePropertyObject(firstObject, secondObject) {
for (let propOfFirst in firstObject) {
for (let propOfSecond in secondObject) {
// Check type of property of object
if (typeof firstObject[propOfFirst] !== typeof secondObject[propOfSecond]) {
return false;
}
// Check key and value inside
// Note that the value can be an array or another object
else if (typeof firstObject[propOfFirst] !== "object" && typeof secondObject[propOfSecond] !== "object") {
return propOfFirst === propOfSecond && firstObject[propOfFirst] === secondObject[propOfSecond];
} else {
if (firstObject[propOfFirst] instanceof Array && secondObject[propOfSecond] instanceof Array) {
return propOfFirst === propOfSecond && compareArray(firstObject[propOfFirst], secondObject[propOfSecond]);
} else {
let arrayConvertedFirst = convertObjectToArrayOfSinglePropertyObject(firstObject[propOfFirst]);
let arrayConvertedSecond = convertObjectToArrayOfSinglePropertyObject(secondObject[propOfSecond]);
return propOfFirst === propOfSecond && compareArray(arrayConvertedFirst, arrayConvertedSecond);
}
}
}
}
}
//***Compare two objects
function compareObject(firstObject, secondObject) {
let first = convertObjectToArrayOfSinglePropertyObject(firstObject);
let second = convertObjectToArrayOfSinglePropertyObject(secondObject);
return compareArray(first, second);
}
//***Compare two array
function compareArray(firstArray, secondArray) {
if (firstArray.length !== secondArray.length) {
return false;
}
let arrayLength = firstArray.length;
for (let i = 0; i < arrayLength; i++) {
if (typeof firstArray[i] !== typeof secondArray[i]) {
return false;
}
// Check whether the element are object or not
// Note that array is object in return
// Check not array/object first
if (typeof firstArray[i] !== "object" && typeof secondArray[i] !== "object") {
if (firstArray[i] !== secondArray[i]) {
return false;
}
}
// Check nested array and nest object
if (typeof firstArray[i] === "object" && typeof secondArray[i] === "object") {
// nested array use recursive
if (firstArray[i] instanceof Array && secondArray[i] instanceof Array) {
if (!compareArray(firstArray[i], secondArray[i])) {
return false;
}
}
// Check for object nest inside using recursive
else {
let firstObjectArray = convertObjectToArrayOfSinglePropertyObject(firstArray[i]);
let secondObjectArray = convertObjectToArrayOfSinglePropertyObject(secondArray[i]);
if (firstObjectArray.length === 1 && secondObjectArray.length === 1) {
if (!compareSinglePropertyObject(firstObjectArray[0], secondObjectArray[0])) {
return false;
}
} else {
if (!compareArray(firstObjectArray, secondObjectArray)) {
return false;
}
}
}
}
}
return true;
}
// What elements that are in first array and not in second array
function arrayDifference(firstArray, secondArray) {
let secondArrayLength = secondArray.length;
let arr = firstArray.filter(element => {
for (let i = 0; i < secondArrayLength; i++) {
// Check special cases first
if (typeof element === "object" && typeof secondArray[i] === "object") {
if (element instanceof Array && secondArray[i] instanceof Array) {
if (compareArray(element, secondArray[i])) {
return false;
}
} else if (compareObject(element, secondArray[i])) {
return false;
}
} else {
if (element === secondArray[i]) {
return false;
}
}
}
return true;
});
return arr;
}

How to detect if an array contains any value that is a specific length

I have an array as follows:
var array = ['Bob','F', 'Nichols'];
I want to detect whether this array contains any values that are a single character long. In other words, I want to know whether there are any initials in this person's name.
var array = ['Bob','F', 'Nichols']; //true
var array = ['B','Freddy', 'Nichols']; //true
var array = ['Bob','Freddy', 'N']; //true
var array = ['B','F', 'N']; //true
var array = ['B','F', 'N']; //true
var array = ['Bob','Freddy', 'Nichols']; //false
if (anyInitials(array)) {
console.log("there are initials");
} else {
console.log("there are no initials");
}
function anyInitials(a) {
var arrayLength = a.length;
var initial = 'no';
for (var i = 0; i < arrayLength; i++) {
if (a[i].length == 1){
initial = 'yes';
}
}
return initial;
}
You can use the function some
let array = ['Bob','F', 'Nichols'];
console.log(array.some(({length}) => length === 1));
let anyInitials = a => a.some(({length}) => length === 1) ? "yes" : "no";
You can use a simple .forEach() loop like below. This loops through the array, and sets isInitial to true if the length is 1.
var array = ['Bob', 'F', 'Nichols'];
function anyInitials(a) {
var isInitial = false;
a.forEach(e => {
if (e.length == 1) {
isInitial = true;
}
});
return isInitial;
}
console.log(anyInitials(array));
You can also use .some() like below. This will return true if any element in the array has a length of 1.
var array = ['Bob', 'F', 'Nichols'];
function anyInitials(a) {
return array.some(e => e.length == 1);
}
console.log(anyInitials(array));

Compare Two Array in Javascript/AngularJS

I want to check two array values are same or not. I am using a form with checkboxes. need show any change in checkbox array or not?. can anyone help me. Two arrays Like this.
array1 = ['1','2','3']; //previous checklist
array2 = ['3','2','1']; //new checklist
Here is a snippet that compares two arrays.
var array1 = [1,2,3];
var array2 = [1,2,3];
var result = array1.length == array2.length && array1.every(function(element, index) {
return element === array2[index];
});
alert(result);
however 1,2,3 in one array is not equal with 3,2,1 in another. You didn't mentioned about to check the array elements or just the array !
In Case you need to compare two arrays with different positions, try this
var array1=[1,2,3,4]
var array2=[1,4,3,2]
var result = array1.length==array2.length && array1.every(function(v,i) { return ($.inArray(v,array2) != -1)})
console.log(result)
I got this:
let arr = ['1', '2', '3'];
let arr2 = ['3', '1', '2'];
let finalResult = arr.length === arr2.length;
arr.forEach(function (item) {
if (!finalResult) {
return;
}
if (arr2.find(function (item2) { return item === item2; }) === undefined) {
finalResult = false;
}
});
console.log(finalResult);
// Warn if overriding existing method
if(Array.prototype.equals)
console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code.");
// attach the .equals method to Array's prototype to call it on any array
Array.prototype.equals = function (array) {
// if the other array is a falsy value, return
if (!array)
return false;
// compare lengths - can save a lot of time
if (this.length != array.length)
return false;
for (var i = 0, l=this.length; i < l; i++) {
// Checking whether the array contains this element
if(isValueExistsInArray(this[i],array) == false) {
return false;
}
}
return true;
}
function isValueExistsInArray(value,compareToArray) {
for(var j = 0, k=compareToArray.length; j<k; j++) {
if(value == compareToArray[j]) {
return true;
}
}
return false;
}
// Hide method from for-in loops
Object.defineProperty(Array.prototype, "equals", {enumerable: false});
array1 = ['1','2','3'];
array2 = ['1','2','3'];
array3 = ['3','2','1'];
array4 = ['3','5','1'];
array5 = ['3','5','1',6];
array1.equals(array2) == true
array1.equals(array3) == true
array1.equals(array4) == false
array1.equals(array5) == false
Finally I have perfect answer for compare two array in javascript.
var array1 = ["1","2","3"];
var arr1 = array1.map(function (x) {
return parseInt(x, 10);
});
var array2 = ["3","2","1"];
var arr2 = array2.map(function (x) {
return parseInt(x, 10);
});
var finalArray1 = arr1.sort();
var finalArray2 = arr2.sort();
var is_same = finalArray1.length == finalArray2.length && finalArray1.every(function(element, index) {
return element === finalArray2[index];
});
if(is_same == true){
console.log('match');
}else{
console.log('not match');
}

counting duplicate arrays within an array in javascript

I have an array of arrays as follows:
[[3, 4], [1, 2], [3, 4]]
I wish to create a new array of arrays that has no duplicates, and has a count of the number of occurrences of each element in the first array:
[[3,4,2], [1,2,1]]
here is what I have so far:
var alreadyAdded = 0;
dataset.forEach(function(data) {
From = data[0];
To = data[1];
index = 0;
newDataSet.forEach(function(newdata) {
newFrom = newData[0];
newTo = newData[1];
// check if the point we are looking for is already added to the new array
if ((From == newFrom) && (To == newTo)) {
// if it is, increment the count for that pair
var count = newData[2];
var newCount = count + 1;
newDataSet[index] = [newFrom, newTo, newCount];
test = "reached here";
alreadyAdded = 1;
}
index++;
});
// the pair was not already added to the new dataset, add it
if (alreadyAdded == 0) {
newDataSet.push([From, To, 1]);
}
// reset alreadyAdded variable
alreadyAdded = 0;
});
I am very new to Javascript, can someone help explain to me what I'm doing wrong? I'm sure there is a more concise way of doing this, however I wasn't able to find an example in javascript that dealt with duplicate array of arrays.
Depending on how large the dataset is that you're iterating over I'd be cautious of looping over it so many times. You can avoid having to do that by creating an 'index' for each element in the original dataset and then using it to reference the elements in your grouping. This is the approach that I took when I solved the problem. You can see it here on jsfiddle. I used Array.prototype.reduce to create an object literal which contained the grouping of elements from the original dataset. Then I iterated over it's keys to create the final grouping.
var dataSet = [[3,4], [1,2], [3,4]],
grouping = [],
counts,
keys,
current;
counts = dataSet.reduce(function(acc, elem) {
var key = elem[0] + ':' + elem[1];
if (!acc.hasOwnProperty(key)) {
acc[key] = {elem: elem, count: 0}
}
acc[key].count += 1;
return acc;
}, {});
keys = Object.keys(counts);
for (var i = 0, l = keys.length; i < l; i++) {
current = counts[keys[i]];
current.elem.push(current.count);
grouping.push(current.elem);
}
console.log(grouping);
Assuming order of sub array items matters, assuming that your sub arrays could be of variable length and could contain items other than numbers, here is a fairly generic way to approach the problem. Requires ECMA5 compatibility as it stands, but would not be hard to make it work on ECMA3.
Javascript
// Create shortcuts for prototype methods
var toClass = Object.prototype.toString.call.bind(Object.prototype.toString),
aSlice = Array.prototype.slice.call.bind(Array.prototype.slice);
// A generic deepEqual defined by commonjs
// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
function deepEqual(a, b) {
if (a === b) {
return true;
}
if (toClass(a) === '[object Date]' && toClass(b) === '[object Date]') {
return a.getTime() === b.getTime();
}
if (toClass(a) === '[object RegExp]' && toClass(b) === '[object RegExp]') {
return a.toString() === b.toString();
}
if (a && typeof a !== 'object' && b && typeof b !== 'object') {
return a == b;
}
if (a.prototype !== b.prototype) {
return false;
}
if (toClass(a) === '[object Arguments]') {
if (toClass(b) !== '[object Arguments]') {
return false;
}
return deepEqual(aSlice(a), aSlice(b));
}
var ka,
kb,
length,
index,
it;
try {
ka = Object.keys(a);
kb = Object.keys(b);
} catch (eDE) {
return false;
}
length = ka.length;
if (length !== kb.length) {
if (Array.isArray(a) && Array.isArray(b)) {
if (a.length !== b.length) {
return false;
}
} else {
return false;
}
} else {
ka.sort();
kb.sort();
for (index = 0; index < length; index += 1) {
if (ka[index] !== kb[index]) {
return false;
}
}
}
for (index = 0; index < length; index += 1) {
it = ka[index];
if (!deepEqual(a[it], b[it])) {
return false;
}
}
return true;
};
// Recursive function for counting arrays as specified
// a must be an array of arrays
// dupsArray is used to keep count when recursing
function countDups(a, dupsArray) {
dupsArray = Array.isArray(dupsArray) ? dupsArray : [];
var copy,
current,
count;
if (a.length) {
copy = a.slice();
current = copy.pop();
count = 1;
copy = copy.filter(function (item) {
var isEqual = deepEqual(current, item);
if (isEqual) {
count += 1;
}
return !isEqual;
});
current.push(count);
dupsArray.push(current);
if (copy.length) {
countDups(copy, dupsArray);
}
}
return dupsArray;
}
var x = [
[3, 4],
[1, 2],
[3, 4]
];
console.log(JSON.stringify(countDups(x)));
Output
[[3,4,2],[1,2,1]]
on jsFiddle
After fixing a typo I tried your solution in the debugger; it works!
Fixed the inner forEach-loop variable name to match case. Also some var-keywords added.
var alreadyAdded = 0;
dataset.forEach(function (data) {
var From = data[0];
var To = data[1];
var index = 0;
newDataSet.forEach(function (newData) {
var newFrom = newData[0];
var newTo = newData[1];
// check if the point we are looking for is already added to the new array
if ((From == newFrom) && (To == newTo)) {
// if it is, increment the count for that pair
var count = newData[2];
var newCount = count + 1;
newDataSet[index] = [newFrom, newTo, newCount];
test = "reached here";
alreadyAdded = 1;
}
index++;
});
// the pair was not already added to the new dataset, add it
if (alreadyAdded == 0) {
newDataSet.push([From, To, 1]);
}
// reset alreadyAdded variable
alreadyAdded = 0;
});
const x = [[3, 4], [1, 2], [3, 4]];
const with_duplicate_count = [
...x
.map(JSON.stringify)
.reduce( (acc, v) => acc.set(v, (acc.get(v) || 0) + 1), new Map() )
.entries()
].map(([k, v]) => JSON.parse(k).concat(v));
console.log(with_duplicate_count);

Categories