JavaScript operation array object merge - javascript

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)

Related

combine array of object if atleast one property is common

//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)

How to join 2 array object using lodash

I want to join a with b using lodash here is my data
const a =
[ { id: 1, job: 'engineer' }
, { id: 2, job: 'police' }
, { id: 3, job: 'thief' }
]
const b =
[ { name: 'test1', score: 1, aId: [ 1, 2 ] }
, { name: 'test2', score: 3, aId: [ 1, 3 ] }
]
Here is my output that I want
const result =
[ { id: 1, job: 'engineer', score: [ {name: 'test1'}, {name: 'test2'} ] }
, { id: 2, job: 'police', score: [] }
, { id: 3, job: 'thief', score: [ {name: 'test 3'} ] }
]
this is what I try I'm using 2 map data and inside the second map I use include check between 2 arrays..
_.map(a, function(data:any) {
const name = _.map(b, function(dataB:any) {
// in here I check
const isValid = dataB.aId.includes(a.id)
if(isValid){
return {
name = dataB.name
}
}
})
return {
id: data.id
job: data.job
score: name
}
});
this method also work but is their any better method than using 2 map ?
Reduce b to a map of id to array of tests, and then map a, and take the relevant array from the map to create each object:
const a =
[ { id: 1, job: 'engineer' }
, { id: 2, job: 'police' }
, { id: 3, job: 'thief' }
]
const b =
[ { name: 'test1', score: 1, aId: [ 1, 2 ] }
, { name: 'test2', score: 3, aId: [ 1, 3 ] }
]
const bMap = b.reduce((acc, { name, aId }) => {
const nameObject = { name }
aId.forEach(id => {
if(!acc.has(id)) acc.set(id, [])
acc.get(id).push(nameObject)
})
return acc
}, new Map())
const result = a.map(o => ({ ...o, scores: bMap.get(o.id) }))
console.log(result)

How to return all the duplicated objects with same values in JS?

is there a clever way to get all objects with same value?
[
{ name: 'a' , value: '123'},
{ name: 'b' , value: '123'},
{ name: 'c' , value: '1234'},
{ name: 'd' , value: '1234'},
{ name: 'e' , value: '12345'},
{ name: 'f' , value: '123456'}
]
the ideal result is:
[
{ name: 'a' , value: '123'},
{ name: 'b' , value: '123'},
{ name: 'c' , value: '1234'},
{ name: 'd' , value: '1234'}
]
I am thinking to count all the occurance of values, but that seems not a good way.
Appreciate!
You could take a Map and filter the array by the value of the map.
var array = [{ name: 'a' , value: '123' }, { name: 'b' , value: '123' }, { name: 'c' , value: '1234' }, { name: 'd' , value: '1234' }, { name: 'e' , value: '12345' }, { name: 'f' , value: '123456' }],
counts = array.reduce((m, { value }) => m.set(value, m.has(value)), new Map),
result = array.filter(({ value }) => counts.get(value));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I think what you are looking for is a sort sort algorithms, and then maybe a filter function.
hope this helps you .
you can sort the code by doing this :
let data = [
{ name: 'a' , value: '123'},
{ name: 'b' , value: '123'},
{ name: 'c' , value: '1234'},
{ name: 'd' , value: '1234'},
{ name: 'e' , value: '12345'},
{ name: 'f' , value: '123456'}
];
let cleanData = data.sort((a, b) = >{
return a.value > b.value;
});
cleanData.filter((data) => data.value === 'requestedValue');
I am not sure about efficiency but this allow you to get the result you want.
By the way you can simply skip the ordering phase i did.
Simplest algorithm, in my opinion, is to create map with values and filter by it. So yes, basically you will count all value occurrences.
Here the example:
const valuesMap = {}
const input = [
{ name: 'a' , value: '123'},
{ name: 'b' , value: '123'},
{ name: 'c' , value: '1234'},
{ name: 'd' , value: '1234'},
{ name: 'e' , value: '12345'},
{ name: 'f' , value: '123456'}
]
input.forEach(item => {
if (!valuesMap[item.value]) {
valuesMap[item.value] = 1
} else {
valuesMap[item.value] += 1
}
})
const output = input.filter(item => {
return valuesMap[item.value] > 1
})
Simple solution use reduce with impurity(No need map again.)
const data = [
{ name: 'a' , value: '123'},
{ name: 'b' , value: '123'},
{ name: 'c' , value: '1234'},
{ name: 'd' , value: '1234'},
{ name: 'e' , value: '12345'},
{ name: 'f' , value: '123456'}
]
const final = []
const counter = (data) => {
return data.reduce((x, i) => {
if(!x[i.value]) x[i.value] = 0
x[i.value]++
if(x[i.value] > 2) final.push(i)
if(x[i.value] > 1) final.push(i, i)
return x;
}, {})
}
counter(data)
console.log(final)

How to compare and change the array of object value in javascript

I have two arrays of objects and want to compare the name and value of them.
const array1 = [
{
name: 'John',
value: null
},
{
name: 'Peter',
value: null
}
]
const array2 = [
{
name: 'John',
value: '0'
}
]
If property name array2 exists on array1 then change the value of name with '0' else do nothing.
The result I expect is :
[
{
"name": "John",
"value": "0"
},
{
"name": "Peter",
"value": null
]
Can anyone show me how to do that?
You can use two forEach() loop for that:
const array1 = [
{
name: 'John',
value: null
},
{
name: 'Peter',
value: null
},
{
name: 'Mike',
value: null
}
]
const array2 = [
{
name: 'John',
value: '0'
},
{
name: 'Mike',
value: '0'
}
]
array2.forEach((item2) => {
array1.forEach((item1) => {
if(item1.name === item2.name){
item1.value = item2.value;
}
});
});
console.log(array1);
its simple :
array1.forEach(record1 => {
array2.forEach(record2 => {
if (record1.name === record2.name) {
record1.value = "0";
}
});
});
You can also map the first array and use find.
Please note this version of the code won't alter/mutate array1's content.
const array1 = [
{
name: 'John',
value: null
},
{
name: 'Peter',
value: null
}
];
const array2 = [
{
name: 'John',
value: '0'
}
];
const result = array1.map(item1 => {
const newItem = {...item1}
if(array2.find(item2 => item2.name === item1.name)) {
newItem.value = 0;
}
return newItem;
});
console.log(result);
its very simple:
you can user the below code :
array2.forEach(
function(parent){
array1.find(function(child)
{
if(child.name==parent.name){
child.value=0;
}
})
}
);
Try this:
const array1 = [
{
name: 'John',
value: null
},
{
name: 'Peter',
value: null
},
{
name: 'Mike',
value: null
}
]
const array2 = [
{
name: 'John',
value: '0'
},
{
name: 'Mike',
value: '0'
}
]
var array = array1.map(x=>{
if(array2.some(function (value) { return value.name === x.name })){
x.value = 0;
}
return x;
})

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