Map and sort two arrays into one [duplicate] - javascript

This question already has answers here:
How can I group an array of objects by key?
(32 answers)
Javascript group objects by property [closed]
(3 answers)
Closed 2 years ago.
I have an object which has two arrays like:
let myData= {
firstArray: [],
seccondArray: []
};
firstArray is an Array which has some data with unique id's like:
firstArray = [
0: { id: 1, name: name1 },
1: { id: 2, name: name2 }
...]
seccondArray is another Array which has some data like:
seccondArray = [
0: { itemId: 1, nameForItem: name1, optionalProperty: property1 },
1: { itemId: 2, nameForItem: name2 },
2: { itemId: 3, nameForItem: name3 },
3: { itemId: 1, nameForItem: name4 }
...]
So I need to create finalArray which will have id and items array inside, where inside items will be pushed all items from seccondArray where the itemId = firstArray.id.
id is the unique id taken firstArray.id. Also the element should be mapped with all its other properties like item1 has for example optionalProperty: property1, so finalArray looks like:
finalArray = [
{ id: 1,
items: [
0: {itemId: 1, nameForItem: name1 , optionalProperty: property1},
1: {itemId: 1, nameForItem: name4}
],},
{id: 2, items: [{itemId: 2, nameForItem: name2}]},
{id: 3, items: [{itemId: 3, nameForItem: name3}]},
{id: 4, items: [{itemId: 4, nameForItem: name4}]}
];

Related

Compare two array of objects and remove objects from first array if a property value is matched

I have 2 array of objects like
const arrayOne = [{id: 1, name: 'one'}, {id: 2, name: 'two'}, {id: 3, name: 'three'}];
const arrayTwo = [{id: 2, name: 'two'}, {id: 3, name: 'three'}];
Here, I need to compare both these arrays and remove matching objects from arrayOne, which should finally give
this.arrayOne = [{id: 1, name: 'one'}];
I tried like below but it is removing all objects from the array
this.arrayOne = this.arrayOne.filter(o1 => this.arrayTwo.some(o2 => o1.id === o2.id));
What I am doing wrong here? Please suggest. Thanks
const arrayOne = [
{ id: 1, name: "one" },
{ id: 2, name: "two" },
{ id: 3, name: "three" },
];
const arrayTwo = [
{ id: 2, name: "two" },
{ id: 3, name: "three" },
];
const arrayTwoIds = new Set(arrayTwo.map((el) => el.id));
const arrayOneFiltered = arrayOne.filter((el) => !arrayTwoIds.has(el.id));
console.log(arrayOneFiltered);
// [ { id: 1, name: 'one' } ]
Depending on the size of the array, creating a set can improve performance, as you do not need to loop over arrayTwo arrayOne.length times but only once. After that, you can look up the existence of an id in arrayTwo in constant time.
Yet, as pointed out in another answer, this is not necessary if the arrays are small (like in your example). In this case, you could also use this one-liner:
arrayOne = arrayOne.filter((elOne) => !arrayTwo.some((elTwo) => elOne.id === elTwo.id));
Here, arrayOne would need to be mutable, i.e. defined with let.
You can find it by comparing it with id.
And arrayOne must be a let.
let arrayOne = [{id: 1, name: 'one'}, {id: 2, name: 'two'}, {id: 3, name: 'three'}];
const arrayTwo = [{id: 2, name: 'two'}, {id: 3, name: 'three'}];
arrayOne = arrayOne.filter(one => !arrayTwo.find(two => one.id == two.id));
console.log(arrayOne);
const arrayOne = [{
id: 1,
name: 'one'
}, {
id: 2,
name: 'two'
}, {
id: 3,
name: 'three'
}];
const arrayTwo = [{
id: 2,
name: 'two'
}, {
id: 3,
name: 'three'
}];
const arrayTwoId = arrayTwo.map(el => (el.id)); // extract id from arrayTwo
const result = arrayOne.filter(el => !arrayTwoId.includes(el.id));
console.log(result);
Extract all the ids from the arrayTwo.
filter those objects who do not match the array of ids of arrayTwo.
Your way is correct. but you miss the not operation (!) before arrayTwo.some.
So the correct way is this:
const arrayOne = [
{id: 1, name: 'one'},
{id: 2, name: 'two'},
{id: 3, name: 'three'}
];
const arrayTwo = [
{id: 2, name: 'two'},
{id: 3, name: 'three'}
];
// Shared Items between arrayOne and arrayTwo (this what you done)
const sharedObjects = arrayOne.filter(o1 => arrayTwo.some(o2 => o1.id === o2.id));
console.log(sharedObjects);
// arrayOne - arrayTwo (this is what you want)
const arrayOneUniqueObjects = arrayOne.filter(o1 => !arrayTwo.some(o2 => o1.id === o2.id));
console.log(arrayOneUniqueObjects);
Also, You can find more details here:
bobbyhadz.com/blog/javascript-get-difference-between-two-arrays-of-objects

What is the best way add all array item in Javascript [duplicate]

This question already has answers here:
Merge/flatten an array of arrays
(84 answers)
Closed 1 year ago.
const arr1 = [
[{ id: 1 }],
[{ id: 2 },{ id: 3 }],
[{ id: 4 }]
];
I want to add all items in this array how can I do this. I want my output as Like:
const arr2 = [
{id:1},
{id:2},
{id:3},
{id:4}
]
Using arr1.flat() will work for your example. If you have an array of even greater depth of nested arrays of objects, you can even use arr1.flat(Infinity) to flatten to a variable depth:
const arr1 = [
{ id: 0 },
[{ id: 1 }],
[{ id: 2 },{ id: 3 }],
[{ id: 4 }]
];
console.log(arr1.flat());

How to merge two array of objects when there is edit flag

I am having the array of objects like below
Array 1:
[{id: 1, name: 'Golden', isEdited: true}, {id: 2, name: 'Pearl'}]
Array 2:
[{id: 1, name: 'Golden'}, {id: 2, name: 'Pearlblue'}, , {id: 3, name: 'Orange'}]
Now i would like to merge the two arrays if the object contains isEdited flag means then that object should not be updated.
Expected result should be
[{id: 1, name: 'Golden', isEdited: true}, {id: 2, name: 'Pearlblue'}, {id: 3, name: 'Orange'}]
I have tried with the below approach
b.map((battr) => {
return {
...a[battr.id],
...battr
}
})
But it returns the output as
[{id: 1, name: 'Golden'}, {id: 2, name: 'Pearlblue'}, {id: 3, name: 'Orange'}]
Be carefull, your ids don't match your array indexes.
Hence in your attempt a[battr.id] should be replaced by something like a.find(a => a.id === battr.id)
Your example is confusing since in both arrays the name is 'Golden' for id=1, but assuming you want only the properties from array A if isEdited=true, your solution could be :
b.map((b_attr) => {
var matchingA = a.find(a_attr => a_attr.id === b_attr.id);
if (matchingA && matchingA.isEdited)
return matchingA;
else
return { ...matchingA, ...b_attr }
})

JavaScript get the element in array of object [duplicate]

This question already has answers here:
How to find object in array by property in javascript?
(3 answers)
Closed 2 years ago.
I have 2 Array:
const arr1 = [
{
id: 1,
name: "a"
},
{
id: 2,
name: "ab"
},
{
id: 3,
name: "abc"
}]
and
const arr2 = [{id:"1"}, {id:"3"}]
How can i get from two above array to get the result like that:
const result = ["a", "abc"]
I'm struggling with array built-in function. Thank you for reading.
You could do something like the following.
const arr1 = [{ id: 1, name: "a"}, {id: 2, name: "ab"}, { id: 3, name: "abc" }]
const arr2 = [{ id: 1 }, { id: 3 }];
const ids = arr2.map(item => item.id);
const includedIds = arr1.filter(item => ids.includes(item.id)).map(item => item.id)
console.log(includedIds)

Set order to array of object in javascript

I need to find a simplest way for setting order to array of objects.
For example, there is an array:
var array = [
{id: 1, name: "Matt"},
{id: 2, name: "Jack"},
{id: 3, name: "Morgan"},
{id: 4, name: "Bruce"}
];
and I have provided
var order = [1,4,2,3];
which refers to object id property of array items.
Now I need to reorder array so it should be like:
var array = [
{id: 1, name: "Matt"},
{id: 4, name: "Bruce"},
{id: 2, name: "Jack"},
{id: 3, name: "Morgan"}
]
Use Array#sort method for sorting and inside custom sort function use Array#indexOf method to get index.
var array = [{
id: 1,
name: "Matt"
}, {
id: 2,
name: "Jack"
}, {
id: 3,
name: "Morgan"
}, {
id: 4,
name: "Bruce"
}];
var order = [1, 4, 2, 3];
array.sort(function(a, b) {
// sort based on the index in order array
return order.indexOf(a.id) - order.indexOf(b.id);
})
console.log(array);
You can also use reduce() on [1,4,2,3] array to return object where keys will be elements and values will be index of each element and then sort by that object.
var array = [
{id: 1, name: "Matt"},
{id: 2, name: "Jack"},
{id: 3, name: "Morgan"},
{id: 4, name: "Bruce"}
];
var s = [1,4,2,3].reduce((r, e, i) => {return r[e] = i, r}, {});
var result = array.sort(function(a, b) {
return s[a.id] - s[b.id];
});
console.log(result)
I guess anything that involves sort can not be more efficient than an O(2n) solution. So i would like to do this job with two reduces as follows;
var arr = [{id: 1, name: "Matt"}, {id: 2, name: "Jack"}, {id: 3, name: "Morgan"}, {id: 4, name: "Bruce"}],
order = [1,4,2,3],
lut = order.reduce((t,e,i) => (t[e] = i,t),{}),
result = arr.reduce((res,obj) => (res[lut[obj.id]] = obj, res) ,[]);
console.log(result);

Categories