Compare two arrays containing objects including other objects, arrays, etc - javascript

Look at these examples of array comparative code:
// example-1
let array1 = ['a', 'b'];
let array2 = ['a', 'b'];
console.log(array1.equals(array2)); // returns true
// example-2
let array1 = ['a', 'b', 1];
let array2 = ['a', 'b', 1];
console.log(array1.equals(array2)); // returns true
// example-3
let array1 = ['a', 'b', {'a': 1, 'b': 2}];
let array2 = ['a', 'b', {'b': 2, 'a', 1}];
console.log(array1.equals(array2)); // returns false
I'm looking for a way to compare the arrays containing objects in them, but irrespective of the order of elements in a nested object, like mentioned in the example-3 above.

You should JSON.stringify() the arrays and compare them like so:
var arr1 = ['a', 'b', {'a': 1}];
var arr2 = ['a', 'b', {'a': 1}];
console.log(JSON.stringify(array1) == JSON.stringify(array2));
This works because it converts arrays of objects into a much simpler comparative state (JSON strings). This will only work if the arrays contain their properties in the same ordered in the OP's example.

underscore way:
_.isEqual(array1, array2)

You can use JSON.stringify() to get the JSON string and compare them with ===:
let array1 = ['a', 'b', {'a': 1}];
let array2 = ['a', 'b', {'a': 1}];
console.log(JSON.stringify(array1) === JSON.stringify(array2)); // returns true

You can just write a function the will recursively check until it gets down to primitives. For example:
function deepEqual(o1, o2){
if (Array.isArray(o1)) {
return Array.isArray(o2)
&& o1.length === o2.length
&& o1.every((item, idx) => deepEqual(item, o2[idx]))
}
if (typeof(o1) == 'object' && o1 != null){ // (typeof null == 'object)
return typeof(o2) == 'object'
&& o2 != null
&& deepEqual(Object.entries(o1)
.sort((a,b) => a[0].localeCompare(b[0])),Object.entries(o2).sort((a,b) => a[0].localeCompare(b[0])))
}
return o1 === o2
}
//Object order doesn't matter
let ob1 = [1, 2, {a: "test", b:"hello"}, 4]
let ob2 = [1, 2, {b:"hello", a: "test", }, 4]
console.log(deepEqual(ob1, ob2))
ob1 = [1, 2, {a: "test", b:"hello"}, 4]
ob2 = [1, 2, {b:"hello", a: "non-test", }, 4]
console.log(deepEqual(ob1, ob2))
// array order matters:
ob1 = [2, 1, {a: "test", b:"hello"}, 4]
ob2 = [1, 2, {b:"hello", a: "test", }, 4]
console.log(deepEqual(ob1, ob2))
console.log(deepEqual("test", "test"))
console.log(deepEqual(null, {a:"test"}))
// etc.

Related

Merge objects from two arrays of object based in the index

i searched a lot about this but i do not find anything that can enlight me about my issue:
I have this code:
let array1 = ["a", "b", 3, {
p1: 'hola'
}, "c", "d"],
array2 = [1, 2, {
p1: 'adios'
}],
result = [],
i, l = Math.min(array1.length, array2.length);
for (i = 0; i < l; i++) {
if (typeof array1[i] === 'object' && typeof array2[i] === 'object') {
result.push(array2[i], ...(JSON.stringify() === JSON.stringify() ?
[] :
[array1[i]]
));
} else {
result.push(array2[i], array1[i]);
}
}
result.push(...array1.slice(l), ...array2.slice(l));
console.log(result);
i have modified the code with the suggestions, right now the code does this:
we have two array;
array1 = ["a", "b", 3, {p1: 'hello'},"c", "d"]
array2 = [1, 2, {p1: 'hello'}]
the result right now is this based in the code:
result: [1, 'a', 2, 'b', {p1: 'hello'}, 3, {p1: 'hello'}, 'c', 'd']
this work fine because i dont want to omit objects that are in different index between the two array, the problem right now is that when the objects in the two array are in the same index this code;
array1 = ["a", "b", {p2: 'goodbye'},"c", "d"]
array2 = [1, 2, {p1: 'hello'}]
result : [1, 'a', 2, 'b', {p1: 'hello'}, 'c', 'd']
This is my issue right now, what i want is that when there are object in the same index on two array compare the properties of the objects and is the same skip the first array object and pass the second to the final array, but if the properties are not the same, combine the properties of the object in one, this is the ideal result that i want:
array1 = ["a", "b", {p2: 'goodbye'},"c", "d"]
array2 = [1, 2, {p1: 'hello'}]
result : [1, 'a', 2, 'b', {p1: 'hello', p2: 'goodbye'}, 'c', 'd']
I think this is what you're after.
let array1 = ['a', 'b', { p2: 'goodbye' }, 'c', 'd'];
let array2 = [1, 2, { p1: 'hello' }];
let result = [];
for (let i = 0; i < Math.max(array1.length, array2.length); i++) {
if (typeof array1[i] == 'object' && typeof array2[i] == 'object') {
result.push({ ...array2[i], ...array1[i] });
} else {
array2[i] && result.push(array2[i]);
array1[i] && result.push(array1[i]);
}
}
console.log(result);
You could compare the items and if same omit the second item.
let array1 = ["a", "b", {p1: 'hello world'},"c", "d"],
array2 = [1, 2, {p1: 'hello world'}],
result = [],
i, l = Math.min(array1.length, array2.length);
for (i = 0; i < l; i++) {
result.push(array2[i], ...(JSON.stringify() === JSON.stringify()
? []
: [array1[i]]
));
}
result.push(...array1.slice(l), ...array2.slice(l));
console.log(result);

JavaScript How to replace first element of an array with each element of another array

I have two arrays and I need to replace the first element of the first array with each elements of the second array:
let firstArray = [
[1, 'a', 'hello'],
[2, 'b', 'world'],
[3, 'c', 'other'],
...
];
let secondArray = [1, 3, 7, ...];
// Result:
// [
// [1, 'a', 'hello'],
// [3, 'b', 'world'],
// [7, 'c', 'other'],
// ...
// ]
I tried doing something like this:
firstArray.map(f => {
secondArray.forEach(s => {
f.splice(0, 1, s);
})
})
But this replace the first element only with the last element of second array
Use .map to transform an array into another:
const firstArray = [
[1, 'a', 'hello'],
[2, 'b', 'world'],
[3, 'c', 'other'],
];
const secondArray = [1, 3, 7];
const transformed = firstArray.map(([, ...rest], i) => [secondArray[i], ...rest]);
console.log(transformed);
Another option:
const firstArray = [
[1, 'a', 'hello'],
[2, 'b', 'world'],
[3, 'c', 'other'],
];
const secondArray = [1, 3, 7];
const transformed = firstArray.map((item, i) => [secondArray[i]].concat(item.slice(1)));
console.log(transformed);
You could assign the array to a new array and take the new value to a specified index.
const
firstArray = [[1, 'a', 'hello'], [2, 'b', 'world'], [3, 'c', 'other']],
secondArray = [1, 3, 7],
result = firstArray.map((a, i) => Object.assign([], a, { 0: secondArray[i] }));
console.log(result);

Filter object with keys in array

I have this array
const array = [1, 3, 6];
and this object
const obj = {
1: {id: 1, foo: 'a', ...},
2: {id: 2, foo: 'b', ...}
3: {id: 3, foo: 'c', ...},
4: {id: 4, foo: 'd', ...},
5: {...},
6: {...}
... // up to 1000 key/value paris
};
I wonder how to filter the obj with the keys in the array.
One way would be
obj.filter(elem => elem.id...);
But that iterates through all the elements in the obj, eventhough there are just three elements in the array.
Better would be to iterate over the array, but
array.filter(elem => elem === obj.id ...);
then only returns the elements from the array(meaning, 1, 3, 6).
What I need is an array looking like
const result = ['s', 'b', 'c', 'd'];
What is the best way to do this?
You can map over the array and and return the key foo from within the object
const res = array.map(elem => obj[elem].foo);
If all elements don't exists in the object you can add a filter condition to remove undefined values
const res = array.map(elem => obj[elem] &&obj[elem].foo).filter(Boolean);
If you have the id as key, you could map the wanted values by filtering the keys for getting only known key and then map the value.
const
array = [1, 3, 6],
object = { 1: { id: 1, foo: 'bar' }, 2: {}, 3: { id: 3, foo: 'foo' }, 4: {}, 5: {} },
result = array
.filter(Object.hasOwnProperty.bind(object))
.map(id => object[id].foo);
console.log(result);
If all the values in array exist in obj then use Array.map else if there are missing entries in obj then can use Array.reduce
const array = [1, 3, 6];
const obj = {1: {id: 1, foo: 'bar'},2: {id: 2, foo: 'foo'}};
const result = array.reduce((a,c) => obj[c] ? a.concat(obj[c].foo) : a, []);;
console.log(result);
You don't need to iterate all the objects you just need to check whether the key is exist or not, if the key is exists you push the foo value to the result array
Here's the code :
const array = [1, 3, 6];
const obj = {
1: {id: 1, foo: 'bar'},
2: {id: 2, foo: 'foo'},
3: {},
4: {},
5: {},
6: {}
};
let result = [];
array.forEach((el) => {
if(obj.hasOwnProperty(el)){
result.push(obj[el].foo)
}
});
console.log(result);

How to put distribute array into arrays of arrays?

I'm new to node js/express. I'm having the problem cause I need to insert bulk in MySQL. I use body-parser, but to simplify my code this is the analogy.
I have two objects from req.body:
Numbers = { 1, 2, 3 }
Letters = { a, b, c }
Then, I need it to be like this,
Object = [ { '1', 'a' }, { '2', 'b' }, { '3', 'c' } ]
What can I use to do this?
const Numbers = [1, 2, 3]
const Letters = ['a', 'b', 'c']
const result = []
Numbers.forEach((el, i) => {
result.push({[el]: Letters[i]})
})
console.log(result)
or
const Numbers = [1, 2, 3]
const Letters = ['a', 'b', 'c']
const result = Numbers.map((el, i) => ({[el]: Letters[i]}))
console.log(result)

How to convert two arrays of same length into one array of objects in javascript?

I have two arrays that look like this:
array1 = [1, 2, 3, 4, 5];
array2 = [a, b, c, d, e];
Using JavaScript, I want to convert two arrays of same length into array of objects that would look like this:
newArrayofObjects = [ {key1: 1, key2: a}, {key1: 2, key2: b}, {key1: 3, key2: c}, {key1: 4, key2: d}, {key1: 5, key2: e}]
Array.map comes in handy a lot.
var newArray = array1.map(function(e,i){return{key1:e,key2:array2[i]}});
var array1 = [1, 2, 3, 4, 5], array2 = ['a', 'b', 'c', 'd', 'e'], newArrayofObjects = [];
for(var key = 0; key < array1.length; key++) {
newArrayofObjects.push({key1 : array1[key], key2 : array2[key]});
}

Categories