Javascript object flatten to array - javascript

I have been trying today to flatten an object array. I cannot achieve what I need, I need to access to inner most element( 1st ) to the outer most element ( 4th ) here is a sample of the data there are some null values which might make it complex:
{
"School":"Arsenal 2011", //4th Element in new array
"Group":{
"Name":"Previous", //3rd Element in new array
"ParentGroup":{
"Name":"Arsenal", //2nd Element in new array
"ParentGroup":{
"Name":"USA", //1st Element in new array
"ParentGroup":null
}
}
},
"GroupDisplayText":null,
"Publisher":"Abbot",
"PublishedDate":"2011",
"PublishersWebsite":"http://google.com/USA/ADW%202011/Arsenal%202011.pdf"
},
{
"School":"New York 2000",
"Group":{
"Name":"New York",
"ParentGroup":{
"Name":"USA",
"ParentGroup":null
}
},
"GroupDisplayText":null,
"Publisher":"DoE",
"PublishedDate":"2000",
"PublishersWebsite":"http://google.com/USA/New York%202000%20Tables.pdf"
}
The output array I would like is:
array[0] = { "USA","Arsenal","Previous" }
array[x] = for all the other data
How would I do this in Javascript?
I have added a plunker if it helps
https://plnkr.co/edit/LNlHArCob4Bix8VYHFwI?p=preview
Thanks

Use Array.prototype.map and _.get() to handle null scenarios
const data = [{
"School":"Arsenal 2011", //4th Element in new array
"Group":{
"Name":"Previous", //3rd Element in new array
"ParentGroup":{
"Name":"Arsenal", //2nd Element in new array
"ParentGroup":{
"Name":"USA", //1st Element in new array
"ParentGroup":null
}
}
},
"GroupDisplayText":null,
"Publisher":"Abbot",
"PublishedDate":"2011",
"PublishersWebsite":"http://google.com/USA/ADW%202011/Arsenal%202011.pdf"
},
{
"School":"New York 2000",
"Group":{
"Name":"New York",
"ParentGroup":{
"Name":"USA",
"ParentGroup":null
}
},
"GroupDisplayText":null,
"Publisher":"DoE",
"PublishedDate":"2000",
"PublishersWebsite":"http://google.com/USA/New York%202000%20Tables.pdf"
}];
const formatted = data.map(item => {
return [
_.get(item, 'Group.ParentGroup.ParentGroup.Name'),
_.get(item, 'Group.ParentGroup.Name'),
_.get(item, 'Group.Name'),
_.get(item, 'School')
];
});
console.log(formatted);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js" integrity="sha256-VeNaFBVDhoX3H+gJ37DpT/nTuZTdjYro9yBruHjVmoQ=" crossorigin="anonymous"></script>

You could take an iterative check for the nested properties.
var data = [{ School: "Arsenal 2011", Group: { Name: "Previous", ParentGroup: { Name: "Arsenal", ParentGroup: { Name: "USA", ParentGroup: null } } }, GroupDisplayText: null, Publisher: "Abbot", PublishedDate: "2011", PublishersWebsite: "http://google.com/USA/ADW%202011/Arsenal%202011.pdf" }, { School: "New York 2000", Group: { Name: "New York", ParentGroup: { Name: "USA", ParentGroup: null } }, GroupDisplayText: null, Publisher: "DoE", PublishedDate: "2000", PublishersWebsite: "http://google.com/USA/New York%202000%20Tables.pdf" }],
result = data.map(({ School, Group: ParentGroup }) => {
var array = [School];
while (ParentGroup) {
array.unshift(ParentGroup.Name);
({ ParentGroup } = ParentGroup);
}
return array;
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

If it was only one level deep, [_.pluck()] would work.(https://lodash.com/docs/3.10.1#pluck)
Gets the property value of path from all elements in collection.
From their example:
var users = [
{ 'user': 'barney', 'age': 36 },
{ 'user': 'fred', 'age': 40 }
];
_.pluck(users, 'user');
// => ['barney', 'fred']
For the nested elements, you can accomplish it with a _.forEach()
Iterates over elements of collection invoking iteratee for each
element.
Loop through the items and in the iteratee function just add the appropriate elements to their respective arrays.

Related

How to return max number arr with the length of subArr?

Products Array has an array property called subArr and my goal is to return an array with the length of subArr which will include biggest numbers.
Array
const products = [
{
name: "car",
subArr: ["4", "200", "599.4", "4444"]
},
{
name: "tv",
subArr: ["44477", "50", "579.2", "3232"]
},
{
name: "glass",
subArr: ["2121.1", "6347", "8867", "90.01"]
}
];
My desired array is [44477, 4444, 8867, 6347]
I tried to map through the main array and the loop through the second one but can't figure out how to get an array with the length of subArr
const products = [
{
name: "car",
numArr: ["4", "200", "599.4", "4444"]
},
{
name: "tv",
numArr: ["44477", "50", "579.2", "3232"]
},
{
name: "glass",
numArr: ["2121.1", "6343", "8867", "90.01"]
}
];
function getMaxFromArr(products) {
if (!products.length) {
return [];
}
return products[0].numArr.map((val, index) => {
return products.map((prod) => parse(prod.numArr[index]));
});
}
const parse = value => parseFloat(value);
const result = getMaxFromArr(products);
console.log("result", result);
Any help will be appreciated
Approach:
First merge the all subArrs by reduce()
Convert them to numbers using .map(Number)
Sort the newArray and finally slice() them.
const products = [ { name: "car", subArr: ["4", "200", "599.4", "4444"] }, { name: "tv", subArr: ["44477", "50", "579.2", "3232"] }, { name: "glass", subArr: ["2121.1", "6347", "8867", "90.01"] } ];
const sortNum = (a, b) => b - a; //descending order
const findMaxArr = (arr, sArrSize) => products.reduce((a, {subArr}) => [...a, ...subArr.map(Number)],[]).sort(sortNum).slice(0, sArrSize);
console.log(findMaxArr(products, products[0].subArr.length));
Judging by your current code you're trying to "zip" the arrays within your products, but for each "column"/index that you zip, you want to grab the max value. That could be achieved by taking the max of your inner array with Math.max() and spreading (...) the mapped numbers into that. You can remove the parse() method as Math.max() will parse the strings to numbers internally.
See your modified code below (I've also modified it to use optional chaining (?.) and the nullish coalescing (??), but you can keep it to use the same if-statement you had if you wish):
const products = [ { name: "car", subArr: ["4", "200", "599.4", "4444"] }, { name: "tv", subArr: ["44477", "50", "579.2", "3232"] }, { name: "glass", subArr: ["2121.1", "6347", "8867", "90.01"] } ];
function getMaxFromArr(products) {
return products[0]?.subArr.map((val, index) =>
Math.max(...products.map((prod) => prod.subArr[index]))
) ?? [];
}
const result = getMaxFromArr(products);
console.log("result", result);
Get all the numbers to a single array using flatMap and convert them to numbers using Number
sort the array of numbers in descending order
take the top n items using slice
const products = [{name:"car",numArr:["4","200","599.4","4444"]},{name:"tv",numArr:["44477","50","579.2","3232"]},{name:"glass",numArr:["2121.1","6343","8867","90.01"]}],
topN = products
.flatMap(p => p.numArr.map(Number))
.sort((a, b) => b - a)
.slice(0, products[0].numArr.length)
console.log(topN)
const products = [{
name: "car",
numArr: ["4", "200", "599.4", "4444"]
},
{
name: "tv",
numArr: ["44477", "50", "579.2", "3232"]
},
{
name: "glass",
numArr: ["2121.1", "6343", "8867", "90.01"]
}
];
function getMaxFromArr(products) {
var BiggestNum = 0;
var BiggestNumArray = [];
if (!products.length) {
return [];
}
products.map((value, index) => {
var Array = value.numArr;
for (let i = 0; i < Array.length; i++) {
if (BiggestNum < Number(Array[i])) {
BiggestNum = Number(Array[i])
BiggestNumArray = Array
}
}
})
return BiggestNumArray
}
const parse = value => parseFloat(value);
const result = getMaxFromArr(products);
console.log("result", result);
I tried not to modify to much your code. You can read the logic in the comments:
Get the length of first numArr
Convert all strings in all numArr props to numbers and save them in a new array
Sort and slice
const products = [
{
name: "car",
numArr: ["4", "200", "599.4", "4444"]
},
{
name: "tv",
numArr: ["44477", "50", "579.2", "3232"]
},
{
name: "glass",
numArr: ["2121.1", "6343", "8867", "90.01"]
}
];
function getMaxFromArr(products) {
let allNumbers = []
if (!products.length) {
return []
}
else{
// get the length of first numArr
let subArrLength = products[0].numArr.length
// convert all strings in all numArr props to numbers and save them in a new array
products.forEach((prod) => {
prod.numArr.forEach((n) => allNumbers.push(Number(n)))
})
// sort and slice
console.log(allNumbers.sort((a,b) => a - b).slice(allNumbers.length - subArrLength))
}
}
getMaxFromArr(products)

How to map or assign an entry to an array-item based on some of this item's conditions?

I have array of objects,
if the name is xx then push xitems to that object and
if the name is yy then push yitems to that object
Below is the code tried , and also should not use spread operator
const result = [];
var ss=arrobj.forEach(function(e){
if(e.name === 'xx'){
result.push({id: e.id, name: e.name, country:e.country, others: xitems})
}
if(e.name === 'yy'){
result.push({id: e.id, name: e.name, country:e.country, others: yitems})
}
return result;
});
var arrobj =[
{id:1, name: "xx", country: "IN"},
{id:2, name: "yy", country: "MY"},
]
xitems =[
{title: "Finance", valid: true}
]
yitems =[
{title: "Sales", valid: true}
]
Expected Output
[
{id:1, name: "xx", country: "IN",
others:[
{title: "Finance", valid: true}
]
},
{id:2, name: "yy", country: "MY",
others: [
{title: "Sales", valid: true}
]
},
]
You should use .map for this.
const arrobj = [
{ id: 1, name: "xx", country: "IN" },
{ id: 2, name: "yy", country: "MY" },
];
const xitems = [{ title: "Finance", valid: true }];
const yitems = [{ title: "Sales", valid: true }];
const result = arrobj.map((item) => {
if (item.name === "xx") {
item.others = xitems;
} else if (item.name === "yy") {
item.others = yitems;
}
return item;
});
console.log(result);
Your code works, the only issue that I identified are.
There is no need to assign var ss with arrobj.forEach. Because Array.forEach donot return a value.
No need of return result; inside Array.forEach.
Also as an improvement you can simply assign the object with key others like Object.assign({}, e, { others: xitems }), rather than returning individual key value.
Working Fiddle
const arrobj = [
{ id: 1, name: "xx", country: "IN" },
{ id: 2, name: "yy", country: "MY" },
]
const xitems = [
{ title: "Finance", valid: true }
]
const yitems = [
{ title: "Sales", valid: true }
]
const result = [];
arrobj.forEach(function (e) {
if (e.name === 'xx') {
result.push(Object.assign({}, e, { others: xitems }))
}
if (e.name === 'yy') {
result.push(Object.assign({}, e, { others: yitems }))
}
});
console.log(result)
Variables are references to an object that has a value, variables do not store values. It is pointless to try to use a variable in that manner unless you have specific parameters. If you insist on a condition then you need to identify xitems and yitems by the objects values and/or properties or by the order they came in. If you have dynamic data how would you know what xitems or yitems really is?
The example below has been made reusable as long as you meet these requirements:
Must have an array of objects as a primary parameter.
Must have at least one array of objects for each object in the primary array. If there's more the rest will be ignored.
The secondary array of objects must be in the order you want then to end up as.
The second parameter is a rest parameter (not a spread operator, although I have no idea why OP does not want to use it). This will allow us to stuff in as many object arrays as we want.
const distOther = (main, ...oAs) => {...
Next we create an array of pairs from all of the secondary arrays
let others = oAs.map(sub => ['others', sub]);
// [['others', [{...}]], [['others', [{...}]], ...]
Then we turn our attention to the primary array. We'll work our way from the inside out. .map() each object as an array of pairs by Object.entries():
main.map((obj, idx) =>
// ...
Object.entries(obj)
// ...
// [{A: 1, B: 2}, {...}] => [[['A', 1], ['B', 2]], [[...], [...]]]
Then .concat() (a spead operator would be more succinct) each array of pairs with that of the secondary array of pairs corresponding to the current index (you'll need to wrap each secondary array in another array, so the return will level off correctly):
// main.map((obj, idx) =>
// ...
// Object.entries(obj)
.concat([others[idx]])));
// [[['A', 1], ['B', 2], ['others', [{...}]], [[...], [...], ['others', [{...}]]]
Finally we'll use Object.fromEntries() to convert each array of pairs into an object.
// main.map((obj, idx) =>
Object.fromEntries(
// Object.entries(obj)
// .concat([others[idx]])));
// [{'A': 1, 'B': 2, 'others': [{...}]},...]
const objArr =[
{id:1, name: "xx", country: "IN"},
{id:2, name: "yy", country: "MY"},
];
const x =[
{title: "Finance", valid: true}
]
const y =[
{title: "Sales", valid: true}
]
const distOther = (main, ...oAs) => {
let others = oAs.map(sub => ['others', sub]);
return main.map((obj, idx) =>
Object.fromEntries(
Object.entries(obj)
.concat([others[idx]])));
};
console.log(distOther(objArr, x, y));
I would choose a map based approach as well but without the if clauses which explicitly check for expected values of the mapped item's name property.
The approach instead utilizes map's 2nd thisArg parameter which gets applied as the mapper functions this context. Such an additional object can be provided as a map/index of custom key value pairs where key equals a mapped item's name.
Thus the mapper implementation features generic code, and due to the this binding it will be provided as function statement which makes it also re-usable and, if properly named, readable / comprehensible / maintainable too.
function assignBoundNamedValueAsOthers(item) {
// the bound key value pairs.
const index = this;
// create new object and assign, according to
// `item.name`, bound named value as `others`.
return Object.assign(
{},
item,
{ others: index[item.name] ?? [] },
);
}
const arrobj = [
{ id: 1, name: "xx", country: "IN" },
{ id: 2, name: "yy", country: "MY" },
];
const xitems = [{ title: "Finance", valid: true }];
const yitems = [{ title: "Sales", valid: true }];
const result = arrobj
.map(assignBoundNamedValueAsOthers, {
// each `key` equals an expected item's `name`.
xx: xitems,
yy: yitems,
});
console.log({
result,
arrobj,
xitems,
yitems,
});
.as-console-wrapper { min-height: 100%!important; top: 0; }
As one can see, the above implementation via Object.assign creates a new object from each mapped arrobj item. Thus the original item-references remains untouched / non mutated. It does not apply for the items of xitems and yitems since both array references are directly assigned each to its newly created others property. The above log does reflect this.
In case the goal was an entirely reference free data structure one needs to slightly change the Object.assign part of assignBoundNamedValueAsOthers ...
function assignBoundNamedValueAsOthers(item) {
// the bound key value pairs.
const index = this;
// create new object and assign, according to
// `item.name`, bound named value as `others`.
return Object.assign(
{},
item, {
others: (index[item.name] ?? [])
// dereference the `others` items as well.
.map(othersItem =>
Object.assign({}, othersItem)
)
},
);
}
const arrobj = [
{ id: 1, name: "xx", country: "IN" },
{ id: 2, name: "yy", country: "MY" },
];
const xitems = [{ title: "Finance", valid: true }];
const yitems = [{ title: "Sales", valid: true }];
const result = arrobj
.map(assignBoundNamedValueAsOthers, {
// each `key` equals an expected item's `name`.
xx: xitems,
yy: yitems,
});
console.log({
result,
arrobj,
xitems,
yitems,
});
.as-console-wrapper { min-height: 100%!important; top: 0; }
In case the OP does not need to care about immutability, the entire process then changes from a map task to a forEach task, where assignBoundNamedValueAsOthers does directly change/mutate each currently processed item of arrobj, thus forEach does not return any data but always the undefined value ...
function assignBoundNamedValueAsOthers(item) {
// the bound key value pairs.
const index = this;
// mutate the original reference of the currently
// processed `item` by directly assigning, according
// to `item.name`, the bound named value as `others`.
Object.assign(
item,
{ others: index[item.name] ?? [] },
);
// no explicit return value due to
// going to be used as a `forEach` task.
}
const arrobj = [
{ id: 1, name: "xx", country: "IN" },
{ id: 2, name: "yy", country: "MY" },
];
const xitems = [{ title: "Finance", valid: true }];
const yitems = [{ title: "Sales", valid: true }];
// mutates each item of `arrobj`.
arrobj.forEach(assignBoundNamedValueAsOthers, {
// each `key` equals an expected item's `name`.
xx: xitems,
yy: yitems,
});
console.log({
arrobj,
xitems,
yitems,
});
.as-console-wrapper { min-height: 100%!important; top: 0; }

Combine data from an array of objects based on one of them

Having an array of objects like this:
[{"event_id":1,"person":"John"},
{"event_id":2,"person":"John"},
{"event_id":3,"person":"Mike"},
{"event_id":1,"person":"Mike"},
{"event_id":1,"person":"Anna"},
{"event_id":3,"person":"Anna"}]
the wanted result should combine them based on the event_id and show them in a table structure like this:
1 John, Mike, Ana
2 John
3 Mike, Anna
Each row represents an event and the rows contains the people who participated in that event.
I don't know how do to this in JavaScript. Any suggestions?
You can use reduce:
const data = [
{ event_id: 1, person: 'John' },
{ event_id: 2, person: 'John' },
{ event_id: 3, person: 'Mike' },
{ event_id: 1, person: 'Mike' },
{ event_id: 1, person: 'Anna' },
{ event_id: 3, person: 'Anna' },
];
const result = data.reduce(
(acc, val) => ({
...acc,
[val.event_id]: acc[val.event_id] ? [...acc[val.event_id], val.person] : [val.person],
}),
{},
);
console.log(result);
You can use a Map with .reduce() to first group your objects, where the event_id is the key in the map, and the value is an array of accumulated person values for the same event_id values. You can then use Array.from() to map each [key, value] entry to a string of HTML for the table rows and data. You can then add this string to your HTML like so:
const arr = [{"event_id":1,"person":"John"},
{"event_id":2,"person":"John"},
{"event_id":3,"person":"Mike"},
{"event_id":1,"person":"Mike"},
{"event_id":1,"person":"Anna"},
{"event_id":3,"person":"Anna"}];
const table = `
<table>
${Array.from(
arr.reduce((m, {event_id:id, person}) => m.set(id, [...(m.get(id) || []), person]), new Map),
([key, arr]) => `<tr><td>${key}</td><td>${arr.join(', ')}</td></tr>`
).join('')}
</table>
`;
document.body.innerHTML = table;
I recommend you to use Map data type.
Map is a collection of keyed data items, just like an Object. But the
main difference is that Map allows keys of any type.
First of all we iterate on Array of Objects, then we check if there is any event_id in Map we push Object.person to the value of event_id entry :
const listOfObjects = [
{ "event_id": 1, "person": "John" },
{ "event_id": 2, "person": "John" },
{ "event_id": 3, "person": "Mike" },
{ "event_id": 1, "person": "Mike" },
{ "event_id": 1, "person": "Anna" },
{ "event_id": 3, "person": "Anna" }];
let eventIdCollection = new Map();
listOfObjects.forEach(obj => {
if (eventIdCollection.has(obj.event_id)) {
let persons = eventIdCollection.get(obj.event_id);
persons.push(obj.person);
eventIdCollection.set(obj.event_id, persons);
}
else {
eventIdCollection.set(obj.event_id, [obj.person]);
}
});
the result is Map of event_id to Array of persons.

iterate an array of object and separe comparing dates in es6

I need to make a function to iterate an array of x objects then compare the date inside the objects and separate in different arrays so I can show separately in the HTML, this is my object:
[{"id":1,"date":"2020-02-06","value":131},{"id":2,"date":"2020-02-06","value":135},{"id":3,"date":"2020-02-06","value":141},{"id":4,"date":"2020-02-05","value":151},{"id":6,"date":"2020-02-05","value":155}]
I want something like this:
obj1 = [{"id":1,"date":"2020-02-06","value":131},{"id":2,"date":"2020-02-06","value":135},{"id":3,"date":"2020-02-06","value":141}]
obj2 = [{"id":4,"date":"2020-02-05","value":151},{"id":6,"date":"2020-02-05","value":155}]
my code:
// global variables
json = [{
"id": 1,
"date": "2020-02-06",
"value": 131
}, {
"id": 2,
"date": "2020-02-06",
"value": 135
}, {
"id": 3,
"date": "2020-02-06",
"value": 141
}, {
"id": 4,
"date": "2020-02-05",
"value": 151
}, {
"id": 6,
"date": "2020-02-05",
"value": 155
}];
obj1 = [];
obj2 = [];
for (const x of json) {
if (x.date != x.date) {
obj1.push(x)
} else {
obj2.push(x)
}
}
console.log(obj1);
console.log(obj2);
in result always the items push into the obj1..
any help is welcome.
The typical solution for this is to group them by the key and push them to an array. Below is an example using Array reduce and Object.values to get it down to the two arrays.
var items = [
{"id":1,"date":"2020-02-06","value":131},
{"id":2,"date":"2020-02-06","value":135},
{"id":3,"date":"2020-02-06","value":141},
{"id":4,"date":"2020-02-05","value":151},
{"id":6,"date":"2020-02-05","value":155}
]
var dateGroups = items.reduce( function (dates, item) {
dates[item.date] = dates[item.date] || []
dates[item.date].push(item)
return dates
}, {})
var results = Object.values(dateGroups)
console.log(results)
You could goup by date and get an array of arrays.
var data = [{ id: 1, date: "2020-02-06", value: 131 }, { id: 2, date: "2020-02-06", value: 135 }, { id: 3, date: "2020-02-06", value: 141 }, { id: 4, date: "2020-02-05", value: 151 }, { id: 6, date: "2020-02-05", value: 155 }],
grouped = data.reduce((r, o) => {
var group = r.find(([{ date }]) => date === o.date);
if (!group) r.push(group = []);
group.push(o);
return r;
}, []);
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can use reduce to build an object that maps each unique date to its respective data items, having, basically, a group by date:
const data = [{"id":1,"date":"2020-02-06","value":131},{"id":2,"date":"2020-02-06","value":135},{"id":3,"date":"2020-02-06","value":141},{"id":4,"date":"2020-02-05","value":151},{"id":6,"date":"2020-02-05","value":155}];
const groupedData = data.reduce((acc, curr) => ({
...acc,
[curr.date]: [...(acc[curr.date] || []), curr]
}), {});
console.log(groupedData);
We also use above the spread syntax and computed property names to make the code shorter.

How do I transform an array to hold data based on a value in the data?

I have seen some questions that might look similar but none is the solution in my case. I want to regroup and recreate my array the way that it is arranged or grouped based on one of my values(age). I want to have all data of the same "age" in one place. So here is my sample array:
[
{
"age": 15,
"person": {
name: 'John',
hobby: 'ski'
},
},
{
"age": 23,
"person": {
name: 'Suzi',
hobby: 'golf'
},
},
{
"age": 23,
"person": {
name: 'Joe',
hobby: 'books'
}
},{
"age": 25,
"person": {
name: 'Rosi',
hobby: 'books'
}
},{
"age": 15,
"person": {
name: 'Gary',
hobby: 'books'
}
},
{
"age": 23,
"person": {
name: 'Kane',
hobby: 'books'
}
}
]
And I need to have an array that kind of have age as a key and person as value, so each key could have multiple values meaning the value will kind of be an array itself.
I have read this and this questions and many more but they were not exactly the same.
I feel like I need to use reduce to count duplicate ages and then filter it based on that but how do I get the values of those ages?
EIDT:
Sorry for not being clear:
This is what I need:
{
23: [
{ name: 'Suzi', hoby: 'golf' },
{ name: 'Joe', hobby: 'books'}
],
15: [
{ name: 'Gary', hobby: 'books' }
] ,
.
.
.
}
You're actually going to want to reduce, not filter. Filtering an Array means to remove elements and place the kept elements into a new container. Reducing an array means to transform it into a single value in a new container. Mapping an array means to transform every value in place to a new container. Since you want to change how the data is represented that's a Reduction, from one form to another more condensed form.
Assume your Array of values is stored in let people = [...]
let peopleByAge = people.reduce(function (accumulator, value, index, array){
// The first time through accumulator is the passed extra Object after this function
// See the MDN for Array.prototype.reduce() for more information
if (accumulator[value.age] == undefined){
accumulator[value.age] = [];
}
accumulator[value.age].push(value);
return accumulator
}, {})
console.log(peopleByAge) // { 23: [{ age: 23, name: ..., hobby: ...}, ...], 13: [...], ...}
You can find the MDN article for Array#reduce() here
Thanks to #RobertMennell who patiently answered me and I voted as answer. But I just wanted to write my version which MDN had a great example of. It is a longer version assuming the people is the array name:
const groupedByvalue = 'age';
const groupedArray = people;
const groupBy = (peopleArray, value) => {
return peopleArray.reduce((acc, obj) => {
const key = obj[value];
if (!acc[key]) {
acc[key] = [];
}
acc[key].push(obj);
return acc;
}, {});
}
console.log(groupBy(groupedArray,groupedByvalue));
Update:
More polished using ternary operator:
const groupedByvalue = 'age';
const groupedArray = people;
const groupBy = (peopleArray, value) => {
return peopleArray.reduce((acc, obj) => {
const key = obj[value];
(!acc[key]) ? (acc[key] = []) : (acc[key].push(obj))
return acc;
}, {});
}
console.log(groupBy(groupedArray,groupedByvalue));

Categories

Resources