Array of objects , group by parent's object - javascript

I've got an array of objects. I want to be able to group objects in parent's object , parent object is determined by broker: true. Is there a way to convert this:
const data = [
{ id: 1, broker: true },
{ id: 2, broker: false },
{ id: 3, broker: false },
{ id: 4, broker: true },
{ id: 5, broker: false },
{ id: 6, broker: true },
{ id: 7, broker: false },
{ id: 8, broker: false },
{ id: 9, broker: false },
];
Into something like this:
const data = [
{ id: 1, broker: true, chunks: [
{ id: 2, broker: false },
{ id: 3, broker: false },
]},
{ id: 4, broker: true, chunks: [
{ id: 5, broker: false },
]},
{ id: 6, broker: true, chunks: [
{ id: 7, broker: false },
{ id: 8, broker: false },
{ id: 9, broker: false },
]},
];

You could check the propery for broker and push either a new object to the result set, or push the object to the previous object's chunks array.
const
data = [{ id: 1, broker: true }, { id: 2, broker: false }, { id: 3, broker: false }, { id: 4, broker: true }, { id: 5, broker: false }, { id: 6, broker: true }, { id: 7, broker: false }, { id: 8, broker: false }, { id: 9, broker: false }],
grouped = data.reduce((r, o) => {
if (o.broker) {
r.push(Object.assign({}, o, { chunks: [] }));
} else {
r[r.length - 1].chunks.push(o);
}
return r;
}, []);
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Use reduce to add to an accumulator every time it runs into a true value, and if it runs into a false value, add to the previous object via the property chunks
data.reduce((a, cv) => {
let len = a.length - 1;
return (cv["broker"]) ? (a.push(cv), a) : (a[len]
["chunks"] || (a[len]["chunks"] = []), a[len]
["chunks"].push(cv), a);
}, []);
const data = [
{ id: 1, broker: true },
{ id: 2, broker: false },
{ id: 3, broker: false },
{ id: 4, broker: true },
{ id: 5, broker: false },
{ id: 6, broker: true },
{ id: 7, broker: false },
{ id: 8, broker: false },
{ id: 9, broker: false },
];
let result = data.reduce((a, cv) => {
let len = a.length - 1;
return (cv["broker"]) ? (a.push(cv), a) : (a[len]["chunks"] || (a[len]["chunks"] = []), a[len]["chunks"].push(cv), a);
}, []);
console.log(result);

You have to go through the array, create a new one and evaluate the condition you need, if it is met, put it in the new array
Object.keys(data).forEach((value, index) => {
// code
})

You are going through the keys of each object
Object.keys(data).forEach(key => {
console.log(data[index].property)
})
found

Related

How to map a object into a object

Having a problem with two arrays of objects and I want to concat data of them related to their id's.
I have two arrays of objects like this:
const data = [
{
default: false,
id: 1,
value: true,
idModule: 1
},
{
default: false,
id: 2,
value: true,
idModule: 1
},
{
default: false,
id: 3,
value: true,
idModule: 2
},
{
default: false,
id: 4,
value: true,
idModule: 2
}
];
const modulData = [
{
name: 'Administration',
id: 1,
},
{
name: 'Benutzerverwaltung',
id: 2,
}
];
Now I want to combine these two related with their idModule == id
to create a new array of objects like this for example:
const result = [
{
name: 'Administration',
id: 1,
modul: [
{
default: false,
id: 1,
value: true,
idModule: 1
},
{
default: false,
id: 2,
value: true,
idModule: 1
},
],
},
{
name: 'Benutzerverwaltung',
id: 2,
modul: [
{
default: false,
id: 3,
value: false,
idModule: 2
},
{
default: false,
id: 4,
value: false,
idModule: 2
},
],
}
];
How can I achieve this?
You can do it simple by using map and filter:
let result = modulData.map(x => {
x.modul = data.filter(d => d.idModule === x.id);
return x;
});
Full code:
const data = [{
default: false,
id: 1,
value: true,
idModule: 1
},
{
default: false,
id: 2,
value: true,
idModule: 1
},
{
default: false,
id: 3,
value: true,
idModule: 2
},
{
default: false,
id: 4,
value: true,
idModule: 2
}
];
const modulData = [{
name: 'Administration',
id: 1,
},
{
name: 'Benutzerverwaltung',
id: 2,
}
];
let result = modulData.map(x => {
x.modul = data.filter(d => d.idModule === x.id);
return x;
});
console.log(result);

compare to arrays of objects and update key in angular 6 typescript

listOne: [
{
id: 1,
compId: 11,
active: false,
},
{
id: 2,
compId: 22,
active: false,
},
{
id: 3,
compId: 33,
active: false,
},
]
listTwo: [
{
id: 1,
compId: 11,
active: true,
},
{
id: 2,
compId: 33,
active: false,
},
]
I have two json, here how to compare with compId key and update the active key in listOne from listTwo if compId is same.
In AngularJs I have tried with below this related link for AngularJs
But how to integrate with Angular 6 with Typescript.
And expected output is
listOne: [
{
id: 1,
compId: 11,
active: true,
},
{
id: 2,
compId: 22,
active: false,
},
{
id: 3,
compId: 33,
active: false,
},
]
You can use map and filter like this
listOne = listOne.map(item => {
let exist = listTwo.filter(c=>c.compId == item.compId)[0];
if(exist != undefined){
item.active = exist.active;
return item;
}else{
return item;
}
});
let listOne= [
{
id: 1,
compId: 11,
active: false,
},
{
id: 2,
compId: 22,
active: false,
},
{
id: 3,
compId: 33,
active: false,
},
]
let listTwo= [
{
id: 1,
compId: 11,
active: true,
},
{
id: 2,
compId: 33,
active: false,
},
]
//let arr3 = [];
listOne = listOne.map(item => {
let exist = listTwo.filter(c=>c.compId == item.compId)[0];
if(exist != undefined){
//item.id = exist.id;
item.active = exist.active;
return item;
}else{
return item;
}
});
console.log(listOne);
Try this,
// Iterate over list one
for(let item of this.listOne){
// Check if the item exist in list two
if(this.listTwo.find(i=>i.compId==item.compId)){
// Update key
item.active = this.listTwo.find(i=>i.compId==item.compId).active;
}
}
I tried and got solution for the question.
So we need to iterate two for to check each data like below.
And need to replace as need
for (const s of listOne) {
for (const r of listTwo) {
if (s.compId === r.compId) {
s.active = r.active;
break;
}
}
}
I have already mentioned the link which the answer available for AngularJS. but i'm looking for Angular 2+ Typescript.

Access elements of Array of Objects

I have an array of objects:
const guests = [
{ id: 1, rsvp: true },
{ id: 2, rsvp: false },
{ id: 3, rsvp: true },
{ id: 4, rsvp: false }
];
I would like to write a function which selects only the objects corresponding to IDs (guests) who have rsvp'd.
function selectGuests(guests, id) {
list.forEach(function(id) {
if(id.true) {
push.SelectGuests();
}
});
return selectGuests;
}
however, I am getting gibberish results.
Any help on this one or points in the right direction would be appreciated!
Cheers!
Use array.filter()
DEMO
const guests = [
{ id: 1, rsvp: true },
{ id: 2, rsvp: false },
{ id: 3, rsvp: true },
{ id: 4, rsvp: false }
];
var result = guests.filter(t=>t.rsvp);
console.log(result);
using forEach
function selectGuests(guests)
{
let result = [];
guests.forEach(function (guest) {
if (guest.rsvp) {
result.push(guest);
}
});
return result;
}
const guests = [
{ id: 1, rsvp: true },
{ id: 2, rsvp: false },
{ id: 3, rsvp: true },
{ id: 4, rsvp: false }
];
let a = selectGuests(guests);
console.log(a);
or simpler using filter method
const guests = [
{ id: 1, rsvp: true },
{ id: 2, rsvp: false },
{ id: 3, rsvp: true },
{ id: 4, rsvp: false }
];
let a = guests.filter(function(item){return item.rsvp});
console.log(a);
here is a simplified version without using es6 features.
function selectGuests(guests) {
var selectedGuests = []
// forEach gets the array elements (one by one) as first param
guests.forEach(function(guest) {
if(guest.rsvp) {
selectedGuests.push(guest)
}
})
return selectedGuests
}
// call it as follows
selectGuests(guests)

How can I filter this dynamic object in javascript?

How can I filter this dynamic object in javascript?
For the below data object is dynamic, I want to filter if the page is same but hasPlan is false.
data = [ { page: 1, hasPlan: false },
{ page: 2, hasPlan: false },
{ page: 3, hasPlan: false },
{ page: 4, hasPlan: false },
{ page: 4, hasPlan: true },
{ page: 5, hasPlan: false },
{ page: 6, hasPlan: false } ];
expected result:
data = [ { page: 1, hasPlan: false },
{ page: 2, hasPlan: false },
{ page: 3, hasPlan: false },
{ page: 4, hasPlan: true },
{ page: 5, hasPlan: false },
{ page: 6, hasPlan: false } ];
First make a map
map = {};
data.forEach( function(item){
map[ String(item.page) ] = map[ String(item.page) ] || item.hasPlan; //notice that if map[ String(item.page) ] is already true, then item.hasPlan is not set.
});
Then iterate the same map and get the output
var output = Object.keys(map).map( s => ({ page : s , hasPlan : map[s] }) )
Demo
var data = [ { page: 1, hasPlan: false },
{ page: 2, hasPlan: false },
{ page: 3, hasPlan: false },
{ page: 4, hasPlan: false },
{ page: 4, hasPlan: true },
{ page: 5, hasPlan: false },
{ page: 6, hasPlan: false } ];
var map = {};
data.forEach( function(item){
map[ String(item.page) ] = map[ String(item.page) ] || item.hasPlan;
})
var output = Object.keys(map).map( s => ({ page : s , hasPlan : map[s] }) );
console.log( output );
My approch would be:
var data = [ { page: 1, hasPlan: false },
{ page: 2, hasPlan: false },
{ page: 3, hasPlan: false },
{ page: 4, hasPlan: false },
{ page: 4, hasPlan: true },
{ page: 5, hasPlan: false },
{ page: 6, hasPlan: false } ];
data.forEach(d => {
if (d.hasPlan){
data.filter(d2 => d2.page === d.page).forEach((d3, i) => {
if(d3.hasPlan === false) {
data.splice(data.indexOf(d3), 1);
}
});
}
});
You could get first an object with all hasPlan pages and then filter the data.
var data = [{ page: 1, hasPlan: false }, { page: 2, hasPlan: false }, { page: 3, hasPlan: false }, { page: 4, hasPlan: false }, { page: 4, hasPlan: true }, { page: 5, hasPlan: false }, { page: 6, hasPlan: false }],
hasPlan = {},
result;
data.forEach(function (o) {
if (o.hasPlan) {
hasPlan[o.page] = true;
}
});
result = data.filter(function (o) {
return !hasPlan[o.page] || o.hasPlan;
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
ES6
var data = [{ page: 1, hasPlan: false }, { page: 2, hasPlan: false }, { page: 3, hasPlan: false }, { page: 4, hasPlan: false }, { page: 4, hasPlan: true }, { page: 5, hasPlan: false }, { page: 6, hasPlan: false }],
hasPlan = new Set(data
.filter(o => o.hasPlan)
.map(o => o.page)
),
result = data.filter(o => !hasPlan.has(o.page) || o.hasPlan);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Javascript MarkActive Function

I am trying to implement a function "markActive", which, when given a list of objects and an id, returns the same list, but with the corresponding object marked active, like for example,
var list = [
{ id: 1, active: false },
{ id: 2, active: false },
{ id: 3, active: true },
{ id: 4, active: false }
];
when function is called
markActive(list, 2);
should Return:
[
{ id: 1, active: false },
{ id: 2, active: true },
{ id: 3, active: false },
{ id: 4, active: false }
]
i tried many loops but everytime i was getting undefined,
thank you in advance.
You could iterate the array and set active with a check of the id.
function markActive(array, id) {
array.forEach(function (o) {
o.active = o.id === id;
});
return list;
}
var list = [{ id: 1, active: false }, { id: 2, active: false }, { id: 3, active: true }, { id: 4, active: false }];
console.log(markActive(list, 2));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Use Array#forEach
var list = [{
id: 1,
active: false
}, {
id: 2,
active: false
}, {
id: 3,
active: true
}, {
id: 4,
active: false
}];
function markActive(list, id) {
list.forEach(function(el) {
if (el.id == id) {
el.active = true;
} else {
el.active = false;
}
});
}
markActive(list, 2);
console.log(list);
Set everything to inactive unless the id should be set to active then do that
function markActive(list, item) {
list.forEach(function(element) {
if (element.active) {
element.active = false;
}
if (element.id === item) {
console.log(item)
element.active = true;
}
})
}

Categories