Reputation: 1665
I have the following array of objects:
[
{
message: 'This is a test',
from_user_id: 123,
to_user_id: 567
},
{
message: 'Another test.',
from_user_id: 123,
to_user_id: 567
},
{
message: 'A third test.',
from_user_id: '456',
to_user_id: 567
}
]
How do I construct a new array of objects where the outermost object key is based on a common key found in the original array?
This is what I'm after:
[
{
123: [
{
message: 'This is a test',
from_user_id: 123,
to_user_id: 567
},
{
message: 'Another test.',
from_user_id: 123,
to_user_id: 567
}
]
},
{
456: [
{
message: 'A third test.',
from_user_id: '456',
to_user_id: 567
}
]
}
]
Notice how in the first array, the user ID of 123
shows up in two objects. That would be the object key for the first element in the new array.
Upvotes: 2
Views: 2435
Reputation: 9658
var users = [
{
message: 'This is a test',
from_user_id: 123,
to_user_id: 567
},
{
message: 'Another test.',
from_user_id: 123,
to_user_id: 567
},
{
message: 'A third test.',
from_user_id: '456',
to_user_id: 567
}
];
console.log(_.groupBy(users,'from_user_id'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
Using Lodash will make it super easy for you. Assuming you have :
var users = [
{
message: 'This is a test',
from_user_id: 123,
to_user_id: 567
},
{
message: 'Another test.',
from_user_id: 123,
to_user_id: 567
},
{
message: 'A third test.',
from_user_id: '456',
to_user_id: 567
}
];
just in one line with Lodash
and you'll get want you want exactly:
users = _.groupBy(users,'from_user_id')
Upvotes: 1
Reputation: 386736
You could use an object and take the from_user_id
property as key for the object. Then push the actual object to the group. For getting the final result, iterate the keys of groups
and build a new object for any group.
var data = [{ message: 'This is a test', from_user_id: 123, to_user_id: 567 }, { message: 'Another test.', from_user_id: 123, to_user_id: 567 }, { message: 'A third test.', from_user_id: '456', to_user_id: 567 }],
groups = Object.create(null),
result;
data.forEach(function (a) {
groups[a.from_user_id] = groups[a.from_user_id] || [];
groups[a.from_user_id].push(a);
});
result = Object.keys(groups).map(function (k) {
var temp = {};
temp[k] = groups[k];
return temp;
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Together with a single loop approach
var data = [{ message: 'This is a test', from_user_id: 123, to_user_id: 567 }, { message: 'Another test.', from_user_id: 123, to_user_id: 567 }, { message: 'A third test.', from_user_id: '456', to_user_id: 567 }],
result = data.reduce(function (groups) {
return function (r, a) {
var temp = {};
if (!groups[a.from_user_id]) {
groups[a.from_user_id] = [];
temp[a.from_user_id] = groups[a.from_user_id];
r.push(temp);
}
groups[a.from_user_id].push(a);
return r;
};
}(Object.create(null)), []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 5
Reputation: 32145
You just need to initialize a results
array, loop over your data array and check if the iterated from_user_id
exists in the results
array, push the iterated object on it, otherwise create a new object with the new from_user_id
key.
This is how should be your code:
var results = [];
arr.forEach(function(obj){
let id = obj["from_user_id"];
if(!results.some(function(r){
return r[id];
})){
let el = {};
el[id] = [];
el[id].push(obj);
results.push(el);
}else{
results.forEach(function(res){
if(res[id]){
res[id].push(obj);
}
});
}
});
Demo:
var arr = [{
message: 'This is a test',
from_user_id: 123,
to_user_id: 567
}, {
message: 'Another test.',
from_user_id: 123,
to_user_id: 567
}, {
message: 'A third test.',
from_user_id: 456,
to_user_id: 567
}];
var results = [];
arr.forEach(function(obj){
let id = obj["from_user_id"];
if(!results.some(function(r){
return r[id];
})){
let el = {};
el[id] = [];
el[id].push(obj);
results.push(el);
}else{
results.forEach(function(res){
if(res[id]){
res[id].push(obj);
}
});
}
});
console.log(results);
Upvotes: 1
Reputation: 633
You could go full functional get all the key filter it out and map it back as a json object
var b = a.map(key => key['from_user_id'])
var c = {}
b.map(elt => c[elt] = a.filter(k => k.from_user_id == elt))
console.log(c)
Upvotes: 4