combine array of object if atleast one property is common - javascript

//this one is actual array
const data = [
{
name: 'shanu',
label: 'ak',
value: 1,
},
{
name: 'shanu',
label: 'pk',
value: 2,
},
{
name: 'bhanu',
label: 'tk',
value: 3,
},
];
>
//and this is the array that I want
let outPut =
[
{
name:'shanu',
label:['ak','pk'],
value:[1,2]
},
{
name:'bhanu',
label:['tk'],
value:[3]
}
]

You can use Array.prototype.reduce() like this:
const data = [
{
name: 'shanu',
label: 'ak',
value: 1,
},
{
name: 'shanu',
label: 'pk',
value: 2,
},
{
name: 'bhanu',
label: 'tk',
value: 3,
},
];
const output = data.reduce((prev, curr) => {
const tmp = prev.find((e) => e.name === curr.name)
if (tmp) {
tmp.label.push(curr.label)
tmp.value.push(curr.value)
} else {
prev.push({
name: curr.name,
label: [curr.label],
value: [curr.value],
})
}
return prev
}, [])
console.log(output)

Related

Filter 2 arrays to check if parent child

I have first array -
let parent = [
{
id:1,
value:"ABC",
},
{
id:2,
value:"DEF",
},
{
id:3,
value:"GHI",
},
{
id:4,
value:"JKL",
},
{
id:5,
value:"MNO",
},
{
id:6,
value:"PQR",
},
]
And 2nd Array Object -
let child = [
{
childid:1,
value:"ABC",
},
{
childid:2,
value:"DEF",
},
{
childid:10,
value:"GHI",
},
]
From parent array I want to select all those elements whose id matches with childid from child array.
I tried -
parent.filter(x=>x.id==child.each(y=>y.childid))
But its not working
You can use some() to do it
let parent = [
{
id:1,
value:"ABC",
},
{
id:2,
value:"DEF",
},
{
id:3,
value:"GHI",
},
{
id:4,
value:"JKL",
},
{
id:5,
value:"MNO",
},
{
id:6,
value:"PQR",
},
]
let child = [
{
childid:1,
value:"ABC",
},
{
childid:2,
value:"DEF",
},
{
childid:10,
value:"GHI",
},
]
let result = parent.filter(p => child.some(a => a.childid == p.id ))
console.log(result)
using Flatmap and filter ...
let parent = [{
id: 1,
value: "ABC",
},
{
id: 2,
value: "DEF",
},
{
id: 3,
value: "GHI",
},
{
id: 4,
value: "JKL",
},
{
id: 5,
value: "MNO",
},
{
id: 6,
value: "PQR",
},
]
let child = [{
childid: 1,
value: "ABC",
},
{
childid: 2,
value: "DEF",
},
{
childid: 10,
value: "GHI",
},
]
const res = parent.flatMap(x => child.filter(y => y.childid === x.id))
console.log(res)
This would work
parent.filter(p => child.some(c => c.childid === p.id))
Wat happens is
For each element in parent array, find the corresponding element in the child array
If it exists the filter will see it as truthy and keep the parent element, if not it will be falsy and filter wil discard it
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
const filterResult = parent.filter(x => child.some(y => y.childid == x.id))
You can use a reduce function along with a forEach to loop through the child elements and compare against the parent.
const result = parents.reduce((acc, parent) => {
children.forEach((child) => {
if (parent.id === child.childid) {
acc.push(parent);
}
});
return acc;
}, []);
console.log(result); // [{"id":1,"value":"ABC"},{"id":2,"value":"DEF"}]
const parents = [{
id: 1,
value: 'ABC',
},
{
id: 2,
value: 'DEF',
},
{
id: 3,
value: 'GHI',
},
{
id: 4,
value: 'JKL',
},
{
id: 5,
value: 'MNO',
},
{
id: 6,
value: 'PQR',
},
];
const children = [{
childid: 1,
value: 'ABC',
},
{
childid: 2,
value: 'DEF',
},
{
childid: 10,
value: 'GHI',
},
];
const result = parents.reduce((acc, parent) => {
children.forEach((child) => {
if (parent.id === child.childid) {
acc.push(parent);
}
return acc;
});
return acc;
}, []);
console.log(result);
MDN Reduce

Extract array from javascript object

I have below javascript object - (named Division)
I want to extract only SubDivs from the array
I tried : -
const division = [{
Name: "DivName1",
Value: "DivValue1",
SubDivision: {
Name: "SubDiv1",
Value: "SubDiv1"
}
},
{
Name: "DivName2",
Value: "DivValue2",
SubDivision: [{
Name: "SubDiv2",
Value: "SubDiv2"
},
{
Name: "SubDiv3",
Value: "SubDiv3"
}
]
}
]
var subDivs = division.map(x => x.SubDivision);
console.log(subDivs)
But this is not giving me array in format -
[{
Name:"SubDiv1",
Value:"SubDiv1"
},
{
Name:"SubDiv2",
Value:"SubDiv2"
},
{
Name:"SubDiv3",
Value:"SubDiv3"
}]
You can use flatMap for that
const division = [{
Name: "DivName1",
Value: "DivValue1",
SubDivision: [{
Name: "SubDiv1",
Value: "SubDiv1"
}]
},
{
Name: "DivName2",
Value: "DivValue2",
SubDivision: [{
Name: "SubDiv2",
Value: "SubDiv2"
},
{
Name: "SubDiv3",
Value: "SubDiv3"
}
]
}
]
const subdivision = division.flatMap(d => d.SubDivision)
console.log(subdivision)
Given your example, all you need to do is call flat on the mapped array:
var subDivs= division.map(x=>x.SubDivision).flat();
Working example:
const division = [{
Name: "DivName1",
Value: "DivValue1",
SubDivision: [{
Name: "SubDiv1",
Value: "SubDiv1"
}
]},
{
Name: "DivName2",
Value: "DivValue2",
SubDivision: [{
Name: "SubDiv2",
Value: "SubDiv2"
},
{
Name: "SubDiv3",
Value: "SubDiv3"
}
]
}
]
var subDivs= division.map(x=>x.SubDivision).flat();
console.log(subDivs)

Transform Object attribute to array of object

I want to merge Array of ObjectA containing ObjectB attribute by ObjectA attribute.
For example :
let myArray = [
{ name: 'Jeu', series: { name: 'testA', value: '89' } },
{ name: 'Dim', series: { name: 'testB', value: '490' } },
{ name: 'Dim', series: { name: 'testC', value: '978' } }
]
And I would like to transform it to
[
{ name: 'Jeu', series: { name: 'testA', value: '89' } },
{ name: 'Dim', series: [{ name: 'testB', value: '490' },{ name: 'testC', value: '978' } ] }
]
Am I able to do that with a simple reduce/map loop ?
You can first use reduce (with some spread syntax) to build an object that maps unique names and objects in the format you want to have, grouping series by name. Then, you can simply get the values from this object.
const myArray = [
{ name: 'Jeu', series: { name: 'testA', value: '89' } },
{ name: 'Dim', series: { name: 'testB', value: '490' } },
{ name: 'Dim', series: { name: 'testC', value: '978' } }
];
const map = myArray.reduce(
(acc, curr) => ({
...acc,
[curr.name]: {
name: curr.name,
series: acc[curr.name]
? [...acc[curr.name].series, curr.series]
: [curr.series]
}
}),
{}
);
const output = Object.values(map);
console.log(output);

JavaScript operation array object merge

I have two arrays, and now I want to merge the two arrays.
The first array:
var data = [
{ name: 'aa', value: 1 },
{ name: 'bb', value: 2 },
{ name: 'cc', value: 3 }
];
Two arrays:
var data2 = [
{ name: 'aa' },
{ name: 'bb' },
{ name: 'cc' },
{ name: 'dd' },
{ name: 'ee' }
];
I want to merge them into this:
var data3 = [
{name: 'aa', value: 1},
{name: 'bb', value: 2},
{name: 'cc', value: 3},
{name: 'dd', value: 0},
{name: 'ee', value: 0}
];
console.log(data3)
At present, my experience is not enough. Please help me solve this problem.
Thanks in advance.
You can try following based on following assumptions
data2 is a collection of names and expecting its length to be always more than length of data
Order of objects can be different
var data = [
{ name: 'aa', value: 1 },
{ name: 'bb', value: 2 },
{ name: 'cc', value: 3 }
];
var data2 = [
{ name: 'aa' },
{ name: 'bb' },
{ name: 'cc' },
{ name: 'dd' },
{ name: 'ee' }
];
// Iterate over the names array
var data3 = data2.map(({name}) => {
// get the matched object in data corresponding to the name
var match = data.find((obj) => obj.name === name);
// if found, return value else default value to 0
return match ? match : {name, value : 0};
});
console.log(data3);
If the input arrays are indeed in order like that, then a simple .map would suffice:
var data = [
{ name: 'aa', value: 1 },
{ name: 'bb', value: 2 },
{ name: 'cc', value: 3 }
];
var data2 = [
{ name: 'aa' },
{ name: 'bb' },
{ name: 'cc' },
{ name: 'dd' },
{ name: 'ee' }
];
const output = data2.map(({ name }, i) => ({ name, value: data[i] ? data[i].value : 0 }));
console.log(output);
Create an object lookup for each name using array#reduce. Extract all the values using the Object.values() from the object lookup.
const data1 = [ { name: 'aa', value: 1 }, { name: 'bb', value: 2 }, { name: 'cc', value: 3 } ],
data2 = [ { name: 'aa' }, { name: 'bb' }, { name: 'cc' }, { name: 'dd' }, { name: 'ee' } ],
result = Object.values([data1, data2].reduce((r,a) => {
a.forEach(({name, value = 0}) => {
r[name] = name in r ? r[name] : {name, value};
});
return r;
},{}));
console.log(result);
You can array#concat both the arrays and using array#reduce create an object lookup and then get all the values using the Object.values().
const data1 = [ { name: 'aa', value: 1 }, { name: 'bb', value: 2 }, { name: 'cc', value: 3 } ],
data2 = [ { name: 'aa' }, { name: 'bb' }, { name: 'cc' }, { name: 'dd' }, { name: 'ee' } ],
result = Object.values(data1.concat(data2).reduce((r,{name, value=0}) => {
r[name] = name in r ? r[name] : {name, value};
return r;
},{}));
console.log(result);
var data = [
{ name: 'aa', value: 1 },
{ name: 'bb', value: 2 },
{ name: 'cc', value: 3 }
];
var data2 = [
{ name: 'aa' },
{ name: 'bb' },
{ name: 'cc' },
{ name: 'dd' },
{ name: 'ee' }
];
let output = new Array(data2.length).fill(data2.length).map(v => new Object());
// Logic
data.forEach((val2)=> {
data2.forEach((val, i)=> {
if (val.name == val2.name){
output[i]["name"] = val.name
output[i]["value"] = val2.value
} else{
output[i]["name"] = val.name
}
})
})
output.map((val,i) => {
if (!val.hasOwnProperty("value")){
console.log(val)
val["value"] = 0
}
})
console.log("------Your Expected Format", output)

Transform the data

I have the following data structure:
const data = [
{
name: 'ABC',
salesData: [
{
timestamp: '2017-09-01',
value: 10
},
{
timestamp: '2017-09-02',
value: 2
}
]
},
{
name: 'DEF',
salesData: [
{
timestamp: '2017-09-01',
value: 8
},
{
timestamp: '2017-09-02',
value: 3
}
]
}
];
I would like to transform this to:
[
{
name: 'ABC',
'2017-09-01': 10,
'2017-09-02': 2
},
{
name: 'CDE',
'2017-09-01': 8,
'2017-09-02': 3
}
]
I'm trying to use Underscore's Chain and Map which I'm getting confused. So far I have the following, not sure how do I write the convertedSalesData to transform as per the need:
_.map(data, function(item) {
let name = item.name;
let salesData = item.salesData;
let convertedSalesData = ?
})
With ES6 you can use spread syntax ... to get this result.
const data = [{"name":"ABC","salesData":[{"timestamp":"2017-09-01","value":10},{"timestamp":"2017-09-02","value":2}]},{"name":"DEF","salesData":[{"timestamp":"2017-09-01","value":8},{"timestamp":"2017-09-02","value":3}]}]
var result = data.map(function({name, salesData}) {
return {name, ...Object.assign({}, ...salesData.map(({timestamp, value}) => ({[timestamp]: value})))}
})
console.log(result)
const data = [{
name: 'ABC',
salesData: [{
timestamp: '2017-09-01',
value: 10
},
{
timestamp: '2017-09-02',
value: 2
}
]
},
{
name: 'DEF',
salesData: [{
timestamp: '2017-09-01',
value: 8
},
{
timestamp: '2017-09-02',
value: 3
}
]
}
];
var res = data.map(function(a) {
var obj = {
name: a.name
};
a.salesData.forEach(function(x) {
obj[x.timestamp] = x.value;
})
return obj;
})
console.log(res);
Similar to #Nenad Vracar. I perfer to use 'reduce':
data.map(({ name, salesData }) => ({
name,
...salesData.reduce(
(record, { timestamp, value }) => {
record[timestamp] = value
return record
},
Object.create(null)
)
}))

Categories

Resources