Here is one option:-
var array = [{
name: "foo1",
value: "val1"
}, {
name: "foo1",
value: ["val2", "val3"]
}, {
name: "foo2",
value: "val4"
}];
var output = [];
array.forEach(function(item) {
var existing = output.filter(function(v, i) {
return v.name == item.name;
});
if (existing.length) {
var existingIndex = output.indexOf(existing[0]);
output[existingIndex].value = output[existingIndex].value.concat(item.value);
} else {
if (typeof item.value == 'string')
item.value = [item.value];
output.push(item);
}
});
console.dir(output);
Answer from BenG on Stack OverflowHere is one option:-
var array = [{
name: "foo1",
value: "val1"
}, {
name: "foo1",
value: ["val2", "val3"]
}, {
name: "foo2",
value: "val4"
}];
var output = [];
array.forEach(function(item) {
var existing = output.filter(function(v, i) {
return v.name == item.name;
});
if (existing.length) {
var existingIndex = output.indexOf(existing[0]);
output[existingIndex].value = output[existingIndex].value.concat(item.value);
} else {
if (typeof item.value == 'string')
item.value = [item.value];
output.push(item);
}
});
console.dir(output);
Here is another way of achieving that goal:
var array = [{
name: "foo1",
value: "val1"
}, {
name: "foo1",
value: [
"val2",
"val3"
]
}, {
name: "foo2",
value: "val4"
}];
var output = array.reduce(function(o, cur) {
// Get the index of the key-value pair.
var occurs = o.reduce(function(n, item, i) {
return (item.name === cur.name) ? i : n;
}, -1);
// If the name is found,
if (occurs >= 0) {
// append the current value to its list of values.
o[occurs].value = o[occurs].value.concat(cur.value);
// Otherwise,
} else {
// add the current item to o (but make sure the value is an array).
var obj = {
name: cur.name,
value: [cur.value]
};
o = o.concat([obj]);
}
return o;
}, []);
console.log(output);
You could use reduce with Object.keys to do that.
var arr = [
{id: 1, tech_id:11, action: 'swim'},
{id: 2, tech_id:11, action: 'run'},
{id: 3, tech_id:22, action: 'climb'},
{id: 4, tech_id:22, action: 'swim'},
{id: 5, tech_id:11, action: 'jump'},
]
let mergeObj = arr.reduce((p, c) => {
const {tech_id, ...otherData} = c;
if (!(tech_id in p)) {
p[tech_id] = {
data: []
}
}
p[tech_id].data.push(otherData)
return p
}, {})
mergeObj = Object.keys(mergeObj).map(key => {
return {
tech_id: key,
data: mergeObj[key].data
}
})
console.log(mergeObj);
You can use the Array reduce and Object Value function to get it done.
var arr = [
{id: 1, tech_id:11, action: 'swim'},
{id: 2, tech_id:11, action: 'run'},
{id: 3, tech_id:22, action: 'climb'},
{id: 4, tech_id:22, action: 'swim'},
{id: 5, tech_id:11, action: 'jump'},
]
const result = Object.values(arr.reduce((item, next) => {
if (!item[next.tech_id]) {
item[next.tech_id] = {
tech_id: next.tech_id,
data: []
};
}
item[next.tech_id].data.push(next);
return item;
}, {}));
console.log(result);
I'd use a temporary object to:
- Loop over
array - For the current object;
- merge (
{...obj1, ...obj2}) current object toreson thetskey
- merge (
- Use
Object.valuesto convert it to the desired array
const array = [{ts: 1596232800, v1: 1}, {ts: 1596232860, v1: 2}, {ts: 1596232920, v1: 3}, {ts: 1596232800, b2: 10}, {ts: 1596232860, b2: 11}, {ts: 1596232920, b2: 12}, {ts: 1596232800, c3: 20}, {ts: 1596232860, c3: 21}, {ts: 1596232920, c3: 22} ];
let res = {};
array.forEach(a => res[a.ts] = {...res[a.ts], ...a});
res = Object.values(res);
console.log(res);
[
{
"ts": 1596232800,
"v1": 1,
"b2": 10,
"c3": 20
},
{
"ts": 1596232860,
"v1": 2,
"b2": 11,
"c3": 21
},
{
"ts": 1596232920,
"v1": 3,
"b2": 12,
"c3": 22
}
]
This can be solved using reduce function mdn.
const array = [
{ts: 1596232800, v1: 1},
{ts: 1596232860, v1: 2},
{ts: 1596232920, v1: 3},
{ts: 1596232800, b2: 10},
{ts: 1596232860, b2: 11},
{ts: 1596232920, b2: 12},
{ts: 1596232800, c3: 20},
{ts: 1596232860, c3: 21},
{ts: 1596232920, c3: 22}
];
const result = array.reduce((acc, value) => {
const fIndex = acc.findIndex(v => v.ts === value.ts);
if (fIndex >= 0) {
acc[fIndex] = { ...acc[fIndex],
...value
}
} else {
acc.push(value);
}
return acc;
}, []);
console.log(result);
var jsonData = [{
Question: "Was the training useful?",
QuestionId: 1,
myData: [{
name: 'No',
value: 1
}]
},
{
Question: "Was the training useful?",
QuestionId: 1,
myData: [{
name: 'Yes',
value: 1
}]
}
];
const result = Object.values(jsonData.reduce((acc, obj) => {
if (!acc[obj.QuestionId]) {
acc[obj.QuestionId] = obj;
} else {
acc[obj.QuestionId].myData = acc[obj.QuestionId].myData ?? []; // if myData is null or undefined, set it to an empty array
acc[obj.QuestionId].myData = acc[obj.QuestionId].myData.concat(obj.myData);
}
return acc;
}, {}));
console.log(result);
function mergeData(data) {
const acc = {}
data.forEach(x => {
const id = x.QuestionId
if (!acc[id]) acc[id] = x
else acc[id].myData = acc[id].myData.concat(x.myData)
})
return Object.values(acc)
}
var obj1 = {name: "John", hobby: "Football"}
var obj2 = {hobby: "Basketball"}
var obj3 = {hobby: "Tennis"}
const merge = (obj1, obj2) => {
Object.keys(obj1).forEach(key => { if (obj2[key]) obj1[key] = [...[obj1[key]], obj2[key]].flat() })
}
merge(obj1, obj2)
merge(obj1, obj3)
console.log(obj1)
const obj1 = {name: "John", hobby: "Football"}
const obj2 = {hobby: "Basketball"}
const obj3 = {}
for (const key in obj1){
if (obj2[key] === undefined){
obj3[key] = obj1[key]
}else{
obj3[key] = [ obj1[key], obj2[key] ]
}
}
console.log(obj3)
Slightly different solution. Does not alter original objects.
You can simply use Array.reduce() to create a map, grouped by name and Object.values() on the map will give your the desired result:
let arr = [ { "name": "Blah", "description": "This is a description" }, { "name": "Foo", "description": "This is a description" }, { "name": "Bar", "description": "This is a description" }, { "name": "Blah", "description": "This is a description" }, { "name": "Test", "description": "This is a description" } ];
let result = Object.values(arr.reduce((a, {name,description})=>{
if(a[name])
a[name].description += "\n" + description;
else
a[name] = Object.assign({},{name,description});
return a;
},{}));
console.log(result);
You could use a lookup object to find duplicates:
const result = [], hash = {};
for(const {name, description} of input) {
if(hash[name]) {
hash[name].description += "\n" + description;
} else {
result.push(hash[name] = { name, description });
}
}
You're example includes invalid syntax for an array.
["topicName":"topic check check","topicName":"topic check popup"]
This could be an array of objects:
[{"topicName":"topic check check"},{"topicName":"topic check popup"}]
Or more likely (how my example is based):
topicName: ["topic check check", "topic check popup"]
Because it is not a one-to-one input to output, it is a good use of Array.prototype.reduce.
list.reduce((acc, row) => {
const existingSel = acc.find(e => e.selectionId === row.selectionId);
// If we don't have an entry, make one.
if (!existingSel) {
// Use expansion of row to avoid mutating source objects
return [ ...acc, { ...row}];
}
if (Array.isArray(existingSel.topicName)) {
// if the topicName is an array, add to it.
existingSel.topicName.push(row.topicName);
} else {
// Otherwise, make it an array with the two options.
existingSel.topicName = [existingSel.topicName, row.topicName];
}
return acc;
}, []);
You can use Array.reduce() to arrange the output according to selectionId. The output array contains objects each with a selectionId and topics array.
const input = [ { "selectionId":1, "topicName":"topic created or not validate" },{ "selectionId":1, "topicName":"hghhhg test test" },{ "selectionId":2, "topicName":"topic test" },{ "selectionId":3, "topicName":"new topic for test topic name and description name(test check)" },{ "selectionId":4, "topicName":"topic check check" },{ "selectionId":4, "topicName":"topic check popup" },{ "selectionId":5, "topicName":"test" } ]
const output = Object.values(input.reduce((acc, cur) => {
acc[cur.selectionId] = acc[cur.selectionId] || { selectionId: cur.selectionId, topics: []};
acc[cur.selectionId].topics.push({ topicName: cur.topicName});
return acc;
}, {}))
console.log('Output:', output);
Run code snippetEdit code snippet Hide Results Copy to answer Expand