Merge several objects into one object and combine properties JavaScript - javascript

I have multiple objects inside an array, I want to merge all the objects that has the same id, but I want to combine all the values from one property as well (In this case, channels)
This is the code:
defaultArray = [
{
id: "FirstId",
name: "Some random name"
channels: [{
id: "Channel-ASD",
name: "Channel ASD"
}]
},
{
id: "FirstId",
name: "Some random name"
channels: [{
id: "Channel-QWE",
name: "Channel QWE"
}]
},
{
id: "SecondId",
name: "Some random name"
channels: [{
id: "Channel-QAZ",
name: "Channel QAZ"
}]
}
];
Expected output:
newArray = [
{
id: "FirstId",
name: "Some random name"
channels: [
{
id: "Channel-ASD",
name: "Channel ASD"
},
{
id: "Channel-QWE",
name: "Channel QWE"
}
]
},
{
id: "SecondId",
name: "Some random name"
channels: [{
id: "Channel-QAZ",
name: "Channel QAZ"
}]
}
]

You need to study about filter, map, reduce, some, ...
let defaultArray = [
{
id: "FirstId",
name: "Some random name",
channels: [{
id: "Channel-ASD",
name: "Channel ASD"
}]
},
{
id: "FirstId",
name: "Some random name",
channels: [{
id: "Channel-QWE",
name: "Channel QWE"
}]
},
{
id: "SecondId",
name: "Some random name",
channels: [{
id: "Channel-QAZ",
name: "Channel QAZ"
}]
}
];
let transformed= defaultArray.reduce((result, item, index, original)=>{
if (result.some(i=>i.id===item.id)) return result;
let channels = original.reduce((r,i)=>{
i.id===item.id && (r=[...r, ...i.channels]);
return r;
},[]);
result.push({
...item,
channels
});
return result;
},[]);
console.log(JSON.stringify(transformed,null,2));

Related

How to keep from each parent only children by id from object

I am trying to keep only children from each parent if it matches a child's id from a given list of parent/child ids.
var parentIds = ['1','2','3'];
var childrenIds = ['2','3','5'];
Parent with id '1' should only have children with id '2', parent with id '2' should only have children with id '3' and parent with id '3' should only have children with id '5'. So, parent id matches children id in same position from both arrays.
Example of initial object:
var object = [
{
name: "parent1",
id: 1,
option_values: [
{
name: "child1",
id: 1
},
{
name: "child2",
id: 2
},
{
name: "child8",
id: 8
}
]
},
{
name: "parent2",
id: 2,
option_values: [
{
name: "child3",
id: 3
},
{
name: "child1",
id: 1
},
{
name: "child9",
id: 9
}
]
},
{
name: "parent3",
id: 3,
option_values: [
{
name: "child5",
id: 5
},
{
name: "child4",
id: 4
},
{
name: "child13",
id: 13
}
]
},
]
Expected result:
var result = [
{
name: "parent1",
id: 1,
option_values: [
{
name: "child2",
id: 2
}
]
},
{
name: "parent2",
id: 2,
option_values: [
{
name: "child3",
id: 3
}
]
},
{
name: "parent3",
id: 3,
option_values: [
{
name: "child5",
id: 5
}
]
},
]
Loop through the objects. Find the index of the parent ID in the parentIds array, then get the corresponding element of childIds. Then filter the option_values array using that child ID.
var object = [{
name: "parent1",
id: 1,
option_values: [{
name: "child1",
id: 1
},
{
name: "child2",
id: 2
},
{
name: "child8",
id: 8
}
]
},
{
name: "parent2",
id: 2,
option_values: [{
name: "child3",
id: 3
},
{
name: "child1",
id: 1
},
{
name: "child9",
id: 9
}
]
},
{
name: "parent3",
id: 3,
option_values: [{
name: "child5",
id: 5
},
{
name: "child4",
id: 4
},
{
name: "child13",
id: 13
}
]
},
];
var parentIds = ['1', '2', '3'];
var childrenIds = ['2', '3', '5'];
object.forEach(obj => {
let idIndex = parentIds.indexOf(String(obj.id));
if (idIndex != -1) {
let childId = parseInt(childrenIds[idIndex]);
obj.option_values = obj.option_values.filter(child => child.id == childId);
}
});
console.log(object);

Filter object array based on category and return list of matches React TS

I am having trouble filtering an object array, based on a given property.
The object array looks something like this:
someData: [{
id: "123",
personData: [
{
personName: "John Smith",
personId: "125443",
categoryId: "B1",
description: "description"
}}]}];
I want to group the personData based on the categoryId, but represent the category grouping by its categoryName (instead of Id as this will not make much sense to the user).
There are a series of categories which are contained in a json in the following format:
const groups = {
data: [
{
categoryName: "Banking",
categoryId: "B1",
description: "Financial sector"
},
{
categoryName: "Retail",
categoryId: "R1",
description: "Retail and customer experience"
}
]
};
How would I go about filtering based on these conditions? All help is much appreciated! I am using react and typescript
Once filtered the data should look like this:
Banking
personName: John Smith
personId: 125443
Retail
personName: Judie Smith
personId: 124938
You can try groupBy on that person data.
const products = [
{ name: 'apples', category: 'fruits' },
{ name: 'oranges', category: 'fruits' },
{ name: 'potatoes', category: 'vegetables' }
];
const groupByCategory = products.groupBy(product => {
return product.category;
});
console.log(groupByCategory);
// {
// 'fruits': [
// { name: 'apples', category: 'fruits' },
// { name: 'oranges', category: 'fruits' },
// ],
// 'vegetables': [
// { name: 'potatoes', category: 'vegetables' }
// ]
// }
I think something along the lines of this function would return what you need.
const data = [
{
categoryName: "Banking",
categoryId: "B1",
description: "Financial sector"
},
{
categoryName: "Retail",
categoryId: "R1",
description: "Retail and customer experience"
}
];
function groupByProperty(arrayOfObjects, property) {
return arrayOfObjects.reduce((acc, curr) => {
const key = curr[property];
if (!acc[key]) {
acc[key] = [];
}
acc[key].push(curr);
return acc;
}, {});
}
const dataByCategoryName = groupByProperty(data, "categoryName");
console.log(dataByCategoryName);
/* Output
{
Banking: [{
categoryId: "B1",
categoryName: "Banking",
description: "Financial sector"
}],
Retail: [{
categoryId: "R1",
categoryName: "Retail",
description: "Retail and customer experience"
}]
}
*/

How to get all the 'items' data from this list?

I have a list of data like below:
The data consist of 6 categories (bags, shoes, girls, bags, and boys) and all of them store the same data (id, items(array: desc, id, imageUrl, name, price), routeName, title).
Now, I want to loop through all categories and just retrieve their name from the 'items', how can I do this?
I have tried the code below and I just can retrieve the name from one of the categories. Are there any ways to get all of the names from all collections? Thanks for helping me.
const { bags, shoes, girls, bags, boys } = collections;
const {items} = bags;
console.log(items.map(item => item.name));
I used this sample data object which mapping with your example. using below array functions can get the result more efficiently.
const data = {
bags: {
id: 1,
items: [
{ desc: "abc", id: 1, imageUrl: "url", name: "Rabbit Crossbody", price:"$10" },
{ desc: "qwe", id: 2, imageUrl: "url", name: "Cat Crossbody", price:"$10" },
{ desc: "pqr", id: 3, imageUrl: "url", name: "Parrot Crossbody", price:"$10" },
],
routeName:"bags",
title:"Bags"
},
boys: {
id: 1,
items: [
{ desc: "abc", id: 1, imageUrl: "url", name: "Lion Crossbody", price:"$10" },
{ desc: "qwe", id: 2, imageUrl: "url", name: "Dog Crossbody", price:"$10" },
{ desc: "pqr", id: 3, imageUrl: "url", name: "Crow Crossbody", price:"$10" },
],
routeName:"boys",
title:"Boys"
},
girls: {
id: 1,
items: [
{ desc: "abc", id: 1, imageUrl: "url", name: "Pig Crossbody", price:"$10" },
{ desc: "qwe", id: 2, imageUrl: "url", name: "Hen Crossbody", price:"$10" },
{ desc: "pqr", id: 3, imageUrl: "url", name: "fish Crossbody", price:"$10" },
],
routeName:"girls",
title:"Girls"
}};
const categories = Object.keys(data); // extract categories
const filteredNames = categories.map(category => {
const items = data[category].items; // extract items of each category
return items.map(item => item.name); // extract names of items into new[]
});
console.log('names', filteredNames.flat());
// ["Rabbit Crossbody", "Cat Crossbody", "Parrot Crossbody", "Lion Crossbody", "Dog Crossbody", "Crow Crossbody", "Pig Crossbody", "Hen Crossbody", "fish Crossbody"]
Try 2 loops:
const allNames = [];
for (const collection of Object.values(collections)) {
for(const item of collection.items) {
allNames.push(item.name);
}
}
console.log(allNames);
It's possible to do this with array functions too, but a loop is often the most obvious.

How to filter an array that excludes from object's property array

let project = {
title: "some title",
participants: [{
_id: "12345678",
name: "John"
}, {
_id: "44332211",
name: "Jackson"
}, {
_id: "55667788",
name: "Steve"
}]
}
let users = [{
_id: "12345678",
name: "John"
}, {
_id: "44332211",
name: "Jackson"
}, {
_id: "09876543",
name: "Aaron"
}, {
_id: "55667788",
name: "Steve"
}, {
_id: "22334455",
name: "Xavier"
}]
How do I list out all the users that are NOT part of the project participants? includes does not work because project is an object...
array.filter + array.some will work:
let project = {
title: "some title",
participants: [{
_id: "12345678",
name: "John"
}, {
_id: "44332211",
name: "Jackson"
}, {
_id: "55667788",
name: "Steve"
}]
}
let users = [{
_id: "12345678",
name: "John"
}, {
_id: "44332211",
name: "Jackson"
}, {
_id: "09876543",
name: "Aaron"
}, {
_id: "55667788",
name: "Steve"
}, {
_id: "22334455",
name: "Xavier"
}]
let result = users.filter(user => !project.participants.some(p => p._id === user._id));
console.log(result);
You can also make use of find with filter:
var users = [{ _id: "12345678", name: "John"}, { _id: "44332211", name: "Jackson"}, { _id: "09876543", name: "Aaron"}, { _id: "55667788", name: "Steve"}, { _id: "22334455", name: "Xavier"}];
var project = { title: "some title", participants: [{ _id: "12345678", name: "John" }, { _id: "44332211", name: "Jackson" }, { _id: "55667788", name: "Steve" }]};
var result = users.filter(k=>!project.participants.find(p=>p._id==k._id));
console.log(result);
Using Array.map and Array.filter
let project = { title: "some title",
participants: [{_id: "12345678", name: "John"},
{_id: "44332211", name: "Jackson"},
{_id: "55667788", name: "Steve"}]
}
let users = [{ _id: "12345678", name: "John"},
{ _id: "44332211", name: "Jackson"},
{ _id: "09876543", name: "Aaron"},
{ _id: "55667788", name: "Steve"},
{ _id: "22334455", name: "Xavier"}];
var participants = project.participants.map(function(p){ return p._id; })
var non_participants = users.filter(function(user){
return participants.indexOf(user._id) == -1;
});
console.log(non_participants);
I would first extract the participant ids into a Set for fast lookup. Then filter the users and check if the id is not included in the set (using has).
let project = {
title: "some title",
participants: [
{ _id: "12345678", name: "John" },
{ _id: "44332211", name: "Jackson" },
{ _id: "55667788", name: "Steve" },
]
};
let users = [
{ _id: "12345678", name: "John" },
{ _id: "44332211", name: "Jackson" },
{ _id: "09876543", name: "Aaron" },
{ _id: "55667788", name: "Steve" },
{ _id: "22334455", name: "Xavier" },
];
const participantIds = new Set(project.participants.map(participant => participant._id));
const usersWithoutProject = users.filter(user => !participantIds.has(user._id));
console.log(usersWithoutProject);

How to fetch data from complex array objects structures?

I have such an object
data: {
dataFirst: {
Food: [ {id: 536131, name: "option1", }]
},
dataSecond: {
Autos: [{id: 678, name: 'option1'}],
Houses: [
{id: 6876, name: "option1"},
{id: 6876, name: "Placed App"},
],
Phones: [
{id: 672, name: "option1"},
{id: 97249, name: "Placed},
],
Food: [
{id: 772, name: "option1"},
{id: 6777, name: "Placed},
],
}
}
The problem is, that I may have same data in dataFirst and dataSecond, for examle 'Food', I have 2 array objects that contains different data but I need to make it one object 'Food' with the data from 2 of them, from the dataFirst 'Food' and dataSecond 'Food'. I had such a code:
export const parser = ({ data }) => {
const result = Object.values(data).reduce((prev, topicsGroup) => {
Object.assign(prev, topicsGroup);
return prev;
}, {});
return result;
}
but this code doesn't unite 2 'Food' objects but returns data only from the dataFirst 'Food' object wihout second one.
You can iterate through all values of your main data object with Object.values(data) and combine them with reduce by concatenating arrays corresponding to common keys:
let data = {
dataFirst: {
Food: [{
id: 536131,
name: "option1",
}]
},
dataSecond: {
Autos: [{
topicId: 678,
name: 'option1'
}],
Houses: [{
topicId: 6876,
name: "option1"
},
{
topicId: 6876,
topicName: "Placed App"
},
],
Phones: [{
topicId: 672,
name: "option1"
},
{
topicId: 97249,
name: "Placed"
},
],
Food: [{
topicId: 772,
name: "option1"
},
{
topicId: 6777,
name: "Placed"
},
],
}
};
let res = Object.values(data).reduce((acc, curr) => {
Object.entries(curr).forEach(([k, v]) => {
if (k in acc) acc[k] = acc[k].concat(v);
else acc[k] = v;
});
return acc;
}, {});
console.log(res);

Categories

Resources