What I want to achieve is to group objects together inside an array if the first two digits of the IDs matches. So given the below array of objects, I want to convert this ORIGINAL ARRAY:
[
{
"id": "0100",
"name": "name 1",
"message": "Lorem blah blah 1"
},
{
"id": "0101",
"name": "",
"message": "Lorem blah blah 1.1"
},
{
"id": "0200",
"name": "name 2",
"message": "Lorem blah blah 2"
},
{
"id": "0201",
"name": "",
"message": "Lorem blah blah 2.1"
},
{
"id": "0202",
"name": "",
"message": "Lorem blah blah 2.2"
},
{
"id": "0300",
"name": "name 3",
"message": "Lorem blah blah 3"
},
{
"id": "0301",
"name": "",
"message": "Lorem blah blah 3.1"
},
{
"id": "0302",
"name": "",
"message": "Lorem blah blah 3.2"
},
{
"id": "0303",
"name": "",
"message": "Lorem blah blah 3.3"
},
{
"id": "0304",
"name": "",
"message": "Lorem blah blah 3.4"
}
]
into this NEW ARRAY:
[
{
"id": "0100",
"name": "name 1",
"message": [
"Lorem blah blah 1",
"Lorem blah blah 1.1"
]
},
{
"id": "0200",
"name": "name 2",
"message": [
"Lorem blah blah 2",
"Lorem blah blah 2.1",
"Lorem blah blah 2.2"
]
},
{
"id": "0300",
"name": "name 3",
"message": [
"Lorem blah blah 3",
"Lorem blah blah 3.1",
"Lorem blah blah 3.2",
"Lorem blah blah 3.3",
"Lorem blah blah 3.4"
]
}
]
The key thing to note is that if the first two digits of the IDs are identical, then add the messages in those objects together as seen in the NEW ARRAY.
As you can all see, @Nenad Vracar has demonstrated a decent answer to the above challenge, however, I have a further question involving yet another array:
`var data2 = [{"CandidateName": "Mary", "relatedId": ["0100"]},{ "CandidateName": "John", "relatedId": ["0200"]},{ "CandidateName":"Peter", "relatedId": ["0300"]},{ "CandidateName": "Paul", "relatedId": ["0300"]}];`
in which I want to pull the 'candidateName' and add it as an array to the original array, "result".
I've tried a data2.forEach loop inside the data1.reduce loop but it seems to hang.
var result = data.reduce(function(r, el) {
// THIS INNER LOOP MAKES THE BROWSER HANG!!!
data2.forEach(function (a){
console.log('a',a);
});
var e = el.id.slice(0, 2);
if (!o[e]) {
o[e] = {
id: el.id,
name: el.name,
message: []
}
r.push(o[e]);
}
o[e].message.push(el.message);
return r;
}, [])
I wonder if there's a more elegant, sophisticated method that will not break?
What I want to achieve is to group objects together inside an array if the first two digits of the IDs matches. So given the below array of objects, I want to convert this ORIGINAL ARRAY:
[
{
"id": "0100",
"name": "name 1",
"message": "Lorem blah blah 1"
},
{
"id": "0101",
"name": "",
"message": "Lorem blah blah 1.1"
},
{
"id": "0200",
"name": "name 2",
"message": "Lorem blah blah 2"
},
{
"id": "0201",
"name": "",
"message": "Lorem blah blah 2.1"
},
{
"id": "0202",
"name": "",
"message": "Lorem blah blah 2.2"
},
{
"id": "0300",
"name": "name 3",
"message": "Lorem blah blah 3"
},
{
"id": "0301",
"name": "",
"message": "Lorem blah blah 3.1"
},
{
"id": "0302",
"name": "",
"message": "Lorem blah blah 3.2"
},
{
"id": "0303",
"name": "",
"message": "Lorem blah blah 3.3"
},
{
"id": "0304",
"name": "",
"message": "Lorem blah blah 3.4"
}
]
into this NEW ARRAY:
[
{
"id": "0100",
"name": "name 1",
"message": [
"Lorem blah blah 1",
"Lorem blah blah 1.1"
]
},
{
"id": "0200",
"name": "name 2",
"message": [
"Lorem blah blah 2",
"Lorem blah blah 2.1",
"Lorem blah blah 2.2"
]
},
{
"id": "0300",
"name": "name 3",
"message": [
"Lorem blah blah 3",
"Lorem blah blah 3.1",
"Lorem blah blah 3.2",
"Lorem blah blah 3.3",
"Lorem blah blah 3.4"
]
}
]
The key thing to note is that if the first two digits of the IDs are identical, then add the messages in those objects together as seen in the NEW ARRAY.
As you can all see, @Nenad Vracar has demonstrated a decent answer to the above challenge, however, I have a further question involving yet another array:
`var data2 = [{"CandidateName": "Mary", "relatedId": ["0100"]},{ "CandidateName": "John", "relatedId": ["0200"]},{ "CandidateName":"Peter", "relatedId": ["0300"]},{ "CandidateName": "Paul", "relatedId": ["0300"]}];`
in which I want to pull the 'candidateName' and add it as an array to the original array, "result".
I've tried a data2.forEach loop inside the data1.reduce loop but it seems to hang.
var result = data.reduce(function(r, el) {
// THIS INNER LOOP MAKES THE BROWSER HANG!!!
data2.forEach(function (a){
console.log('a',a);
});
var e = el.id.slice(0, 2);
if (!o[e]) {
o[e] = {
id: el.id,
name: el.name,
message: []
}
r.push(o[e]);
}
o[e].message.push(el.message);
return r;
}, [])
I wonder if there's a more elegant, sophisticated method that will not break?
Share Improve this question edited Sep 25, 2016 at 11:28 Mr. Benedict asked Sep 22, 2016 at 9:13 Mr. BenedictMr. Benedict 8272 gold badges10 silver badges15 bronze badges 3- It seems to be a sorted array – passion Commented Sep 22, 2016 at 9:20
- How do I extend this question without losing momentum if I were I to ask it as a fresh question? May I ask my question in ments in here? if so, here goes? – Mr. Benedict Commented Sep 25, 2016 at 11:21
-
I e seeking further help. I have yet another array:
var data2 = [{"CandidateName": "Mary", "relatedId": ["0100"]},{ "CandidateName": "John", "relatedId": ["0200"]},{ "CandidateName":"Peter", "relatedId": ["0300"]},{ "CandidateName": "Paul", "relatedId": ["0300"]}];
in which I want to pull the 'candidateName' and add it as an array to the original array, "result". I've tried a data2.forEach loop inside the data1.reduce loop but it seems to hang. I wonder if there's a more elegant, sophisticated method that will not break? – Mr. Benedict Commented Sep 25, 2016 at 11:21
2 Answers
Reset to default 6You can use reduce()
to return array and one object for grouping.
var data = [{"id":"0100","name":"name 1","message":"Lorem blah blah 1"},{"id":"0101","name":"","message":"Lorem blah blah 1.1"},{"id":"0200","name":"name 2","message":"Lorem blah blah 2"},{"id":"0201","name":"","message":"Lorem blah blah 2.1"},{"id":"0202","name":"","message":"Lorem blah blah 2.2"},{"id":"0300","name":"name 3","message":"Lorem blah blah 3"},{"id":"0301","name":"","message":"Lorem blah blah 3.1"},{"id":"0302","name":"","message":"Lorem blah blah 3.2"},{"id":"0303","name":"","message":"Lorem blah blah 3.3"},{"id":"0304","name":"","message":"Lorem blah blah 3.4"}];
var o = {}
var result = data.reduce(function(r, el) {
var e = el.id.slice(0, 2);
if (!o[e]) {
o[e] = {
id: el.id,
name: el.name,
message: []
}
r.push(o[e]);
}
o[e].message.push(el.message);
return r;
}, [])
console.log(result)
You could check for double zeroes and add the new group to the result set.
var data = [{ "id": "0100", "name": "name 1", "message": "Lorem blah blah 1" }, { "id": "0101", "name": "", "message": "Lorem blah blah 1.1" }, { "id": "0200", "name": "name 2", "message": "Lorem blah blah 2" }, { "id": "0201", "name": "", "message": "Lorem blah blah 2.1" }, { "id": "0202", "name": "", "message": "Lorem blah blah 2.2" }, { "id": "0300", "name": "name 3", "message": "Lorem blah blah 3" }, { "id": "0301", "name": "", "message": "Lorem blah blah 3.1" }, { "id": "0302", "name": "", "message": "Lorem blah blah 3.2" }, { "id": "0303", "name": "", "message": "Lorem blah blah 3.3" }, { "id": "0304", "name": "", "message": "Lorem blah blah 3.4" }],
grouped = [];
data.forEach(function (a) {
var key = a.id.slice(0, 2);
if (a.id === key + '00') {
this[key] = { id: a.id, name: a.name, message: [] };
grouped.push(this[key]);
}
this[key].message.push(a.message);
}, Object.create(null));
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }