Update an array using another array based on matched property value - javascript

I have two arrays like this
let array1 = [{
'id': 1,
'name': 'A'
}, {
'id': 2,
'name': 'B'
}, {
'id': 3,
'name': 'C'
}]
let array2 = [{
'id': 1,
'name': 'x'
}, {
'id': 2,
'name': 'y'
}]
I want to update array 1 with the array 2 object values which are matching based on id values.
Result would be something like this.
[{
'id': 1,
'name': 'x'
}, {
'id': 2,
'name': 'y'
}, {
'id': 3,
'name': 'C'
}]
I have written something like this but not working .
array1.forEach(item1 => {
const itemFromArr2 = array2.find(item2 => item2.id== item1.id);
if (itemFromArr2) {
item1= itemFromArr2;
}
}
)
Please suggest me how to do this.

You might want to check this one-liner out:
array1.map(e => (e.name = array2.find(a => a.id == e.id)?.name || e.name, e));
Explanation: We are mapping over array1 and searching for the matching id in array2, if it is found (array2.find(a => a.id == e.id)?.name), we override the name property (e.name = ...), otherwise we keep it as it is (... || e.name).
Small example:
let array1 = [{
'id': 1,
'name': 'A'
}, {
'id': 2,
'name': 'B'
}, {
'id': 3,
'name': 'C'
}]
let array2 = [{
'id': 1,
'name': 'x'
}, {
'id': 2,
'name': 'y'
}]
const newarray = array1.map(e => (e.name = array2.find(a => a.id == e.id)?.name || e.name, e));
console.log(newarray);
Edit according to #Roster's comment, if you want to override the whole entry use this line:
array1.map(e => (e = array2.find(a => a.id == e.id) || e, e));
Second example:
let array1 = [{
'id': 1,
'name': 'A'
}, {
'id': 2,
'name': 'B'
}, {
'id': 3,
'name': 'C'
}]
let array2 = [{
'id': 1,
'name': 'x'
}, {
'id': 2,
'name': 'y',
'otherproperty': 42
}]
const newarray = array1.map(e => (e = array2.find(a => a.id == e.id) || e, e));
console.log(newarray);

Using a hashmap to update the array.
The reason of hashmap is for performance.
const array1 = [
{ id: 1, name: "A" },
{ id: 2, name: "B" },
{ id: 3, name: "C" },
];
const array2 = [
{ id: 1, name: "x" },
{ id: 2, name: "y" },
];
const hashMap2 = array2.reduce((carry, item) => {
const { id } = item;
if (!carry[id]) {
carry[id] = item;
}
return carry;
}, {});
const output = array1.map(item => {
const newName = hashMap2[item.id]?.name;
if (newName) {
item.name = newName;
}
return item;
});
console.log(output);

Here's a solution using Generics:
const array1 = [{
'id': 1,
'name': 'A'
}, {
'id': 2,
'name': 'B'
}, {
'id': 3,
'name': 'C'
}]
const array2 = [{
'id': 1,
'name': 'x'
}, {
'id': 2,
'name': 'y'
}]
function mergeArray<T>(arr1: T[], arr2: T[], identifier: keyof T): T[] {
for(const oItem of arr2){
const itemInArr1 =
arr1.find(item => item[identifier] === oItem[identifier]);
if(itemInArr1){
for(const key in itemInArr1){
itemInArr1[key] = oItem[key];
}
} else {
arr1.push(oItem);
}
}
return arr1;
}
console.log(mergeArray(array1,array2, 'id'));
Playground
This iterates over the itmes in array2and checks their existence inside array1 based on the identifier.
Based on whether or not the item exists in array1, the item will be modified, or the item from array2 is pushed into array1.

Convert the update array to a Map, then iterate the target array with Array.map(), and merge it with the object of the same key in the upateMap if it exists:
const fn = (predicate, target, update) => {
const updateMap = new Map(update.map(o => [predicate(o), o]))
return target.map(o => {
const key = predicate(o)
return updateMap.has(key)
? { ...o, ...updateMap.get(key)}
: o
})
}
const array1 = [{"id":1,"name":"A"},{"id":2,"name":"B"},{"id":3,"name":"C"}]
const array2 = [{"id":1,"name":"x"},{"id":2,"name":"y"}]
const result = fn(o => o.id, array1, array2);
console.log(result);
With types (TS playground):
const fn = <T>(predicate: (arg: T) => any, target: T[], update: T[]) => {
const updateMap = new Map(update.map(o => [predicate(o), o]))
return target.map(o => {
const key = predicate(o)
return updateMap.has(key)
? { ...o, ...updateMap.get(key)}
: o
})
}

Related

Compare two arrays of objects, and remove if object value is equal

I've tried modifying some of the similar solutions on here but I keep getting stuck, I believe I have part of this figured out however, the main caveat is that:
Some of the objects have extra keys, which renders my object comparison logic useless.
I am trying to compare two arrays of objects. One array is the original array, and the other array contains the items I want deleted from the original array. However there's one extra issue in that the second array contains extra keys, so my comparison logic doesn't work.
An example would make this easier, let's say I have the following two arrays:
const originalArray = [{id: 1, name: "darnell"}, {id: 2, name: "funboi"},
{id: 3, name: "jackson5"}, {id: 4, name: "zelensky"}];
const itemsToBeRemoved = [{id: 2, name: "funboi", extraProperty: "something"},
{id: 4, name: "zelensky", extraProperty: "somethingelse"}];
after running the logic, my final output should be this array:
[{id: 1, name: "darnell"}, {id: 3, name: "jackson5"}]
And here's the current code / logic that I have, which compares but doesn't handle the extra keys. How should I handle this? Thank you in advance.
const prepareArray = (arr) => {
return arr.map((el) => {
if (typeof el === "object" && el !== null) {
return JSON.stringify(el);
} else {
return el;
}
});
};
const convertJSON = (arr) => {
return arr.map((el) => {
return JSON.parse(el);
});
};
const compareArrays = (arr1, arr2) => {
const currentArray = [...prepareArray(arr1)];
const deletedItems = [...prepareArray(arr2)];
const compared = currentArray.filter((el) => deletedItems.indexOf(el) === -1);
return convertJSON(compared);
};
How about using filter and some? You can extend the filter condition on select properties using &&.
const originalArray = [
{ id: 1, name: 'darnell' },
{ id: 2, name: 'funboi' },
{ id: 3, name: 'jackson5' },
{ id: 4, name: 'zelensky' },
];
const itemsToBeRemoved = [
{ id: 2, name: 'funboi', extraProperty: 'something' },
{ id: 4, name: 'zelensky', extraProperty: 'somethingelse' },
];
console.log(
originalArray.filter(item => !itemsToBeRemoved.some(itemToBeRemoved => itemToBeRemoved.id === item.id))
)
Or you can generalise it as well.
const originalArray = [
{ id: 1, name: 'darnell' },
{ id: 2, name: 'funboi' },
{ id: 3, name: 'jackson5' },
{ id: 4, name: 'zelensky' },
];
const itemsToBeRemoved = [
{ id: 2, name: 'funboi', extraProperty: 'something' },
{ id: 4, name: 'zelensky', extraProperty: 'somethingelse' },
];
function filterIfSubset(originalArray, itemsToBeRemoved) {
const filteredArray = [];
for (let i = 0; i < originalArray.length; i++) {
let isSubset = false;
for (let j = 0; j < itemsToBeRemoved.length; j++) {
// check if whole object is a subset of the object in itemsToBeRemoved
if (Object.keys(originalArray[i]).every(key => originalArray[i][key] === itemsToBeRemoved[j][key])) {
isSubset = true;
}
}
if (!isSubset) {
filteredArray.push(originalArray[i]);
}
}
return filteredArray;
}
console.log(filterIfSubset(originalArray, itemsToBeRemoved));
Another simpler variation of the second approach:
const originalArray = [
{ id: 1, name: 'darnell' },
{ id: 2, name: 'funboi' },
{ id: 3, name: 'jackson5' },
{ id: 4, name: 'zelensky' },
];
const itemsToBeRemoved = [
{ id: 2, name: 'funboi', extraProperty: 'something' },
{ id: 4, name: 'zelensky', extraProperty: 'somethingelse' },
];
const removeSubsetObjectsIfExists = (originalArray, itemsToBeRemoved) => {
return originalArray.filter(item => {
const isSubset = itemsToBeRemoved.some(itemToBeRemoved => {
return Object.keys(item).every(key => {
return item[key] === itemToBeRemoved[key];
});
});
return !isSubset;
});
}
console.log(removeSubsetObjectsIfExists(originalArray, itemsToBeRemoved));
The example below is a reusable function, the third parameter is the key to which you compare values from both arrays.
Details are commented in example
const arr=[{id:1,name:"darnell"},{id:2,name:"funboi"},{id:3,name:"jackson5"},{id:4,name:"zelensky"}],del=[{id:2,name:"funboi",extraProperty:"something"},{id:4,name:"zelensky",extraProperty:"somethingelse"}];
/** Compare arrayA vs. delArray by a given key's value.
--- ex. key = 'id'
**/
function deleteByKey(arrayA, delArray, key) {
/* Get an array of only the values of the given key from delArray
--- ex. delList = [1, 2, 3, 4]
*/
const delList = delArray.map(obj => obj[key]);
/* On every object of arrayA compare delList values vs
current object's key's value
--- ex. current obj[id] = 2
--- [1, 2, 3, 4].includes(obj[id])
Any match returns an empty array and non-matches are returned
in it's own array.
--- ex. ? [] : [obj]
The final return is a flattened array of the non-matching objects
*/
return arrayA.flatMap(obj => delList.includes(obj[key]) ? [] : [obj]);
};
console.log(deleteByKey(arr, del, 'id'));
let ff = [{ id: 1, name: 'darnell' }, { id: 2, name: 'funboi' },
{ id: 3, name: 'jackson5' },
{ id: 4, name: 'zelensky' }]
let cc = [{ id: 2, name: 'funboi', extraProperty: 'something' },
{ id: 4, name: 'zelensky', extraProperty: 'somethingelse' }]
let ar = []
let out = []
const result = ff.filter(function(i){
ar.push(i.id)
cc.forEach(function(k){
out.push(k.id)
})
if(!out.includes(i.id)){
// console.log(i.id, i)
return i
}
})
console.log(result)

How to randomly select exam 2 items of a category and each from others categories?

Suppose an array of objects:
arr1 = [
{ 'catId': 1, 'name': 'A' },
{ 'catId': 2, 'name': 'B' },
{ 'catId': 3, 'name': 'C' },
{ 'catId': 2, 'name': 'D' },
{ 'catId': 1, 'name': 'E' },
{ 'catId': 1, 'name': 'F' },
{ 'catId': 3, 'name': 'G' },
{ 'catId': 3, 'name': 'H' },
{ 'catId': 2, 'name': 'I' },
{ 'catId': 1, 'name': 'J' }
]
How can I randomly choose two Item of catId=1 and each Items from remaining category.
Required
arr2 = [
{ 'catId': 1, 'name': 'A' },
{ 'catId': 1, 'name': 'F' },
{ 'catId': 2, 'name': 'I' },
{ 'catId': 3, 'name': 'G' }
]
This is a very simple and naïve approach like I explained on my comment, but it gets the job done:
var arr1 = [
{ 'catId': 1, 'name': 'A' },
{ 'catId': 2, 'name': 'B' },
{ 'catId': 3, 'name': 'C' },
{ 'catId': 2, 'name': 'D' },
{ 'catId': 1, 'name': 'E' },
{ 'catId': 1, 'name': 'F' },
{ 'catId': 3, 'name': 'G' },
{ 'catId': 3, 'name': 'H' },
{ 'catId': 2, 'name': 'I' },
{ 'catId': 1, 'name': 'J' }
];
//shuffles an array
function shuffle(arr) {
return arr.sort(() => Math.random() - 0.5);
}
//gets items with catId = 1, and shuffles them
var cat1 = shuffle(arr1.filter(function(item) {
return item.catId == 1;
}));
var otherCat = [];
//pushes items in the otherCat array that aren't catId = 1, and not duplicate category
for (var i = 0; i < arr1.length; i++) {
//if not catId = 1 and not already in array
if (arr1[i].catId != 1 && !find(arr1[i])) {
//get all items in this category, and shuffles them to get a random item
var thisCat = shuffle(arr1.filter(function(item) { return item.catId == arr1[i].catId; }))[0];
otherCat.push(thisCat);
}
}
//finds an item in otherCat array by catId
function find(item) {
return otherCat.find(function(i) {
return item.catId === i.catId;
});
}
var result = [];
result.push(cat1[0]);
result.push(cat1[1]);
//concatenate both arrays
Array.prototype.push.apply(result, otherCat);
console.log(JSON.stringify(result));
I coded it this way because it is very simple to see. You could in theory loop through the whole array once to get all catId = 1 and other catId into 2 different arrays (I know I am doing multiple passes to the array, but like I said, this is just so you can get the idea).
Another way of doing it (perhaps a little more complex) is by grouping the items by category, then looping thru each category and grabbing a random element (2 in the case of catId == 1):
var arr1 = [
{ 'catId': 1, 'name': 'A' },
{ 'catId': 2, 'name': 'B' },
{ 'catId': 3, 'name': 'C' },
{ 'catId': 2, 'name': 'D' },
{ 'catId': 1, 'name': 'E' },
{ 'catId': 1, 'name': 'F' },
{ 'catId': 3, 'name': 'G' },
{ 'catId': 3, 'name': 'H' },
{ 'catId': 2, 'name': 'I' },
{ 'catId': 1, 'name': 'J' }
];
//groups by a property
//https://stackoverflow.com/a/34890276/752527
var groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
//shuffles an array
function shuffle(arr) {
return arr.sort(() => Math.random() - 0.5);
}
var result = [];
var grouped = groupBy(arr1, 'catId');
var keys = Object.keys(grouped);
for (var i = 0; i < keys.length; i++) {
var group = grouped[keys[i]]
//if i have items in my group, shuffle them and grab 1, or 2 items from it
if (group && group.length > 0) {
var cat = shuffle(group);
result.push(cat[0]);
//adds the second item with catId ==1
if (group[0].catId === 1) {
result.push(cat[1]);
}
}
}
console.log(JSON.stringify(result));
If you want to return a list of n-number of items from a particular category and one from the remaining categories, then you could group the items by their catId and then map the entries to a randomized count (length) based on whether the current key is the chosen bias.
Edit: I added a bias to keep n-number of items from the category of choice.
const categories = [
{ 'catId': 1, 'name': 'A' }, { 'catId': 2, 'name': 'B' },
{ 'catId': 3, 'name': 'C' }, { 'catId': 2, 'name': 'D' },
{ 'catId': 1, 'name': 'E' }, { 'catId': 1, 'name': 'F' },
{ 'catId': 3, 'name': 'G' }, { 'catId': 3, 'name': 'H' },
{ 'catId': 2, 'name': 'I' }, { 'catId': 1, 'name': 'J' }
];
const sortFn = (
{ catId: ai, name: an },
{ catId: bi, name: bn }
) =>
(ai - bi) || an.localeCompare(bn);
const main = () => {
print(pickRand(categories, ({ catId }) => catId, 1, 2).sort(sortFn));
};
const shuffle = (arr) => arr.sort(() => Math.random() - 0.5);
const grouped = (arr, keyFn) => arr.reduce((acc, item, idx) =>
({ ...acc, [keyFn(item)]: [...(acc[keyFn(item)] ?? []), idx] }), {});
const pickRand = (arr, keyFn, bias, count) =>
Object
.entries(grouped(arr, keyFn))
.flatMap(([key, idx]) =>
shuffle(idx).slice(0, bias == key ? count : 1)
.map(i => arr[i]));
const print = (arr) => console.log(arr.map(x => JSON.stringify(x)).join('\n'));
main();
.as-console-wrapper { top: 0; max-height: 100% !important; }

Get possible combinations for array of objects by type and values

I need to create every combination of objects possible out of an array with types/identifiers. E.g.:
Input:
let inputArray =
[
{
'type': '1',
'values': [
'val1',
'val2'
]
},
{
'type': '2',
'values': [
'val1',
'val2',
'val3'
]
}
]
Output:
let outputArray =
[
[
{
'type': '1',
'value': 'val1'
},
{
'type': '2',
'value': 'val1'
}
],
[
{
'type': '1',
'value': 'val1'
},
{
'type': '2',
'value': 'val2'
}
],
[
{
'type': '1',
'value': 'val1'
},
{
'type': '2',
'value': 'val3'
}
],
[
{
'type': '1',
'value': 'val2'
},
{
'type': '2',
'value': 'val1'
}
],
[
{
'type': '1',
'value': 'val2'
},
{
'type': '2',
'value': 'val2'
}
],
[
{
'type': '1',
'value': 'val2'
},
{
'type': '2',
'value': 'val3'
}
],
]
And it needs to work dynamically depending on the number of types, and values inside the input array. I.E. the input array has another object, where that objects values array has 3 or 4 elements...
What I tried:
function doTheThing(inputArray) {
let outputArray = []
for (let element of inputArray) {
for (let value of element.values) {
outputArray.push({ type: element.type, value: value })
}
}
}
Which gives me every value possible, but doesn't give me every combination that I need...
You can create recursive function using simple for loop that exists when the value of n is larger then the length of the data or continues to increment it and then runs for loop.
let data = [{"type":"1","values":["val1","val2"]},{"type":"2","values":["val1","val2","val3"]}]
function f(data, n = 0, prev = []) {
const result = [];
if (n > data.length - 1) {
result.push(prev.slice())
return result;
}
const { type, values } = data[n];
for (let i = 0; i < values.length; i++) {
prev[n] = { type, value: values[i] }
result.push(...f(data, n + 1, prev))
}
return result;
}
const result = f(data);
console.log(JSON.stringify(result, 0, 4))
Or you could use the reduce method instead of the for loop and make recursive call as long as the n < data.length - 1
let data = [{"type":"1","values":["val1","val2"]},{"type":"2","values":["val1","val2","val3"]}]
function f(data, n = 0, prev = []) {
return data[n].values.reduce((r, value) => {
prev[n] = { type: data[n].type, value }
if (n === data.length - 1) {
r.push(prev.slice())
}
if (n < data.length - 1) {
r.push(...f(data, n + 1, prev))
}
return r;
}, [])
}
const result = f(data);
console.log(JSON.stringify(result, 0, 4))
This function can help us to extend a permutation:
let permute = (iterable, arr) => {
let vals = [ ...iterable ];
let result = [];
for (let v of arr)
for (let items of vals)
result.push([ v, ...items ]);
return result;
};
For example if we want to permute [ 'a', 'b' ], [ 1, 2 ], and [ '?', '!' ] we can do:
let permute = (iterable, arr) => {
let vals = [ ...iterable ];
let result = [];
for (let v of arr)
for (let items of vals)
result.push([ v, ...items ]);
return result;
};
let v1 = permute([ [] ], [ 1, 2 ]);
let v2 = permute(v1, [ 'a', 'b' ]);
let v3 = permute(v2, [ '?', '!' ]);
console.log(JSON.stringify({ v1, v2, v3 }));
You can use this function with inputArray after performing a basic transformation on it (to achieve the type of result you posted in your question). For an entry in inputArray like { type: '1', values: [ 'v1', 'v2' ] }, you need to convert that to a form like: [ { type: '1', value: 'v1' }, { type: '1', value: 'v2' } ].
// Your original data
let inputArray = [{'type': '1','values': ['val1','val2']},{'type': '2','values': ['val1','val2','val3']}];
// Function to format data as described
let format = arr => arr.map(({ type, values }) => values.map(value => ({ type, value })));
// The same `permute` function as before
let permute = (iterable, arr) => { let vals = [ ...iterable ]; let result = []; for (let v of arr) for (let items of vals) result.push([ v, ...items ]); return result; };
let formatted = format(inputArray);
let v1 = permute([ [] ], formatted[0]);
let v2 = permute(v1, formatted[1]);
console.log(JSON.stringify(v2, null, 2));

How to filter an array of object with an array of numbers

Given an array of objects arr1 how can I filter out to a new array the objects that do not have a property equal to any value in the array of numbers arr2
const arr1 = [
{
key: 1,
name: 'Al'
},
{
key: 2,
name: 'Lo'
},
{
key: 3,
name: 'Ye'
}
];
const arr2 = [2, 3]
// Failed attempt
const newArr = arr1.filter(obj1 => arr2.some(num1 => num1 !== obj1.key))
console.log(newArr)
// Expected: [{ key: 1, name: 'Al' }]
// Received: [
// { key: 1, name: 'Al' },
// { key: 2, name: 'Lo' },
// { key: 3, name: 'Ye' }
// ]
Using your syntax:
You have to match on the somein case it's the same and not different. Then if it matches, do not keep the value.
const arr1 = [
{
key: 1,
name: 'Al',
},
{
key: 2,
name: 'Lo',
},
{
key: 3,
name: 'Ye',
},
];
const arr2 = [2, 3];
const newArr= arr1.filter(x => !arr2.some(y => y === x.key));
console.log(newArr);
Alternative syntax below :
const arr1 = [{
key: 1,
name: 'Al',
},
{
key: 2,
name: 'Lo',
},
{
key: 3,
name: 'Ye',
},
];
const arr2 = [2, 3];
const newArr = arr1.filter(({
key,
}) => !arr2.some(y => y === key));
console.log(newArr);
That said, you should be using Array.includes() like some ppl answered. It's simplier for the same outcome
const arr1 = [{
key: 1,
name: 'Al',
},
{
key: 2,
name: 'Lo',
},
{
key: 3,
name: 'Ye',
},
];
const arr2 = [2, 3];
const newArr = arr1.filter(({
key,
}) => !arr2.includes(key));
console.log(newArr);
You can do this
const newArr = arr1.filter(obj => !arr2.includes(obj.key));
This will work for you:
const arr1 = [
{
key: 1,
name: 'Al'
},
{
key: 2,
name: 'Lo'
},
{
key: 3,
name: 'Ye'
}
];
const arr2 = [2, 3]
const filtered = arr1.filter(val => !arr2.includes(val.key))
console.log(filtered)
:)
For situations like this Set is also very cool (and for big arrays more performant):
const arr1 = [
{
key: 1,
name: 'Al'
},
{
key: 2,
name: 'Lo'
},
{
key: 3,
name: 'Ye'
}
];
const arr2 = [2, 3]
const arr2Set = new Set(arr2);
const newArr = arr1.filter(obj1 => !arr2Set.has(obj1.key))
console.log(newArr)
You can use indexOf like this:
const newArr = arr1.filter(obj => arr2.indexOf(obj.key) > -1);
You need to filter the arr1 when arr1 element does not exist in arr2, so I think it could be better to use indexOf() like this
const newArr = arr1.filter(obj1 => arr2.indexOf(obj1.key) === -1)
if the element does not exist in arr2 it will return -1 which what you need.

How to create array of array by grouping ids

I have an array:
let array = [{id: 1, name:'a'}, {id: 2, name: 'b'},{id: 1, name:'c'}];
I want an array like
arr2 = [[{id: 1, name:'a'}, {id: 1, name:'c'}], [{id: 2, name: 'b'}]]
I tried this but I cant find which array to add to:
$scope.journalsArray = response.data.body.Data;
$scope.newArray = [];
let idsArray = [];
for (let i = 0; i < $scope.journalsArray.length; i++) {
if(idsArray.indexOf($scope.journalsArray[i].journal_id) != -1){
$scope.newArray.push($scope.journalsArray[i]);
}else{
$scope.idsArray.push($scope.journalsArray[i].journal_id);
}
}
Array.reduce over your original array.
If a group exists that has an item with the same id, push into it.
Otherwise create the group.
let array = [{id: 1, name:'a'}, {id: 2, name: 'b'},{id: 1, name:'c'}]
let result = array.reduce((acc, item) => {
const group = acc.find(group => group.find(inner => inner.id === item.id))
if (group)
group.push(item)
else
acc.push([item])
return acc
}, [])
console.log(result)
Using reduce(), find() and filter() methods we can achieve this
let array = [
{id: 1, name:'a'},
{id: 2, name: 'b'},
{id: 1, name:'c'}
];
const results = arr => {
return arr.reduce((result, item ) => {
if (!result.find(obj => obj[0].id === item.id)) {
result.push(array.filter(val => val.id == item.id))
}
return result;
}, [])
}
console.log(results(array));
// ​​​​​[ [ { id: 1, name: 'a' }, { id: 1, name: 'c' } ], [ { id: 2, name: 'b' } ] ]​​
You could take a Map and collect the objects in the same group. Then get the values of each group as result.
var array = [{ id: 1, name:'a' }, { id: 2, name: 'b' },{ id: 1, name:'c' }],
result = Array.from(
array
.reduce((m, o) => m.set(o.id, [...(m.get(o.id) || []), o]), new Map)
.values()
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Using Array#reduce, Map, destructuring and Array#concat.
const data = [{id: 1, name:'a'}, {id: 2, name: 'b'},{id: 1, name:'c'}];
const res = data.reduce((a,{id,name})=>{
return a.set(id, [{id,name}].concat(a.get(id)||[]));
}, new Map()).values();
console.log([...res]);
let array = [{id: 1, name:'a'}, {id: 2, name: 'b'},{id: 1, name:'c'}]
let result = array.reduce((acc, item) => {
const group = acc.find(group => group.find(inner => inner.id === item.id))
if (group)
group.push(item)
else
acc.push([item])
return acc
}, [])
console.log(result)
let array = [{id: 1, name:'a'}, {id: 2, name: 'b'},{id: 1, name:'c'}]
let result = array.reduce((acc, item) => {
const group = acc.find(group => group.find(inner => inner.id === item.id))
if (group)
group.push(item)
else
acc.push([item])
return acc
}, [])
console.log(result)

Categories