I have an array of objects say temp. I want to group based on the properties of object. For example, the gender should be grouped and its count also be calculated.
const temp = [
{
properties: {
"id":1234,
"gender": 'male',
"status": "Active"
}
},
{
properties: {
"id":1456,
"gender": 'male',
"status": "Not Active"
}
},
{
properties: {
"id":1377,
"gender": 'female',
"status": "Active"
}
},
{
properties: {
"id":8799,
"gender": 'female',
"status": "Active"
}
}
];
The needed props to be grouped can be passed like
groupFunc = (data) => {
const metrics = data
for (i = 0; i < temp.length; i++) {
data.map( el =>
temp[i].properties.el ? grouped.push([{"key": el, "value": temp[i].properties.el,"count":1}])
:
null
)
console.log(temp[i].properties)
}
};
groupFunc(["gender","status"]);
The end result after grouping and accumulating its count should be
grouped = [
[
{
"key": "gender",
"value": "male",
"count": 2
},
{
"key": "gender",
"value": "female",
"count": 2
}
],
[
{
"key": "status",
"value": "Active",
"count": 3
},
{
"key": "status",
"value": "Not Active",
"count": 1
},
]
]
I have an array of objects say temp. I want to group based on the properties of object. For example, the gender should be grouped and its count also be calculated.
const temp = [
{
properties: {
"id":1234,
"gender": 'male',
"status": "Active"
}
},
{
properties: {
"id":1456,
"gender": 'male',
"status": "Not Active"
}
},
{
properties: {
"id":1377,
"gender": 'female',
"status": "Active"
}
},
{
properties: {
"id":8799,
"gender": 'female',
"status": "Active"
}
}
];
The needed props to be grouped can be passed like
groupFunc = (data) => {
const metrics = data
for (i = 0; i < temp.length; i++) {
data.map( el =>
temp[i].properties.el ? grouped.push([{"key": el, "value": temp[i].properties.el,"count":1}])
:
null
)
console.log(temp[i].properties)
}
};
groupFunc(["gender","status"]);
The end result after grouping and accumulating its count should be
grouped = [
[
{
"key": "gender",
"value": "male",
"count": 2
},
{
"key": "gender",
"value": "female",
"count": 2
}
],
[
{
"key": "status",
"value": "Active",
"count": 3
},
{
"key": "status",
"value": "Not Active",
"count": 1
},
]
]
Share
asked Jun 29, 2020 at 9:57
ReNinjaReNinja
5732 gold badges11 silver badges28 bronze badges
4 Answers
Reset to default 2
const temp = [{properties:{"id":1234,"gender":'male',"status":"Active"}},{properties:{"id":1456,"gender":'male',"status":"Not Active"}},{properties:{"id":1377,"gender":'female',"status":"Active"}},{properties:{"id":8799,"gender":'female',"status":"Active"}}];
const groupByKeys = (data, keys) => {
let finalResult = keys.map(key => {
return Object.values(data.reduce((result, obj)=>{
let objKey = obj["properties"][key]
result[objKey] = result[objKey] || {key: key, count: 0, value: objKey};
result[objKey].count += 1;
return result
},{}))
})
return finalResult
}
console.log(groupByKeys(temp, ["gender", "status"]))
const temp = [
{
properties: {
"id":1234,
"gender": 'male',
"status": "Active"
}
},
{
properties: {
"id":1456,
"gender": 'male',
"status": "Not Active"
}
},
{
properties: {
"id":1377,
"gender": 'female',
"status": "Active"
}
},
{
properties: {
"id":8799,
"gender": 'female',
"status": "Active"
}
}
];
const count = (arr, key) => arr.reduce( (acc, curr) => {
let k = curr[key]
if(!acc.map(a => a.value).includes(k)) {
acc = [...acc, {
key,
value: k,
count: 1
}]
}
acc.map(a => a.value == k ? {...a, count: a.count + 1} : a)
return acc;
} , [])
data = temp.map(t => t.properties)
groupFunc = (keys) => keys.map(k => count(data, k))
const res = groupFunc(["gender","status"]);
console.log(res)
You can use reduce
to achieve your desired functionality like below.
Added explanation into code.
const temp = [{properties:{"id":1234,"gender":'male',"status":"Active"}},{properties:{"id":1456,"gender":'male',"status":"Not Active"}},{properties:{"id":1377,"gender":'female',"status":"Active"}},{properties:{"id":8799,"gender":'female',"status":"Active"}}];
const groupFunc = (data, props) => {
// https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
// reduce has two params callback function and initialValue : optional.
// here I have call back function (a, i) => {...}
// add initialValue = []
let resultGroups = data.reduce((a, i) => {
// loop through each properties
props.forEach(p => {
// get index of matching value with result object a and current object data.
let index = a.findIndex(x => x.key === p && x.value === i.properties[p]);
// if index = -1 then no such value exists. So add new value. else increment count
if (index === -1) {
a.push({ key: p, value: i.properties[p], count: 1 });
} else {
a[index].count++;
}
});
// return result object (aka accumulator in reduce function)
return a;
}, []);
let result = [];
// loop through each property and create group for each property.
props.forEach(p => {
// check if there is any object available with this property.
// If yes then filter object and push into result array.
if (resultGroups.some(x => x.key === p)) {
result.push(resultGroups.filter(x => x.key === p));
}
});
// return result.
return result;
};
console.log(groupFunc(temp, ["gender", "status"]));
// JavaScript Document
/* I changed the properties to non string */
const temps = [
{
properties: {
id:1234,
gender: 'male',
status: "Active"
}
},
{
properties: {
id:1456,
gender: 'male',
status: "Not Active"
}
},
{
properties: {
id:1377,
gender: 'female',
status: "Active"
}
},
{
properties: {
id:8799,
gender: 'female',
status: "Active"
},
}
];
/* finding filtering elements with "map" method */
const filterEleman1 = temps.map(temp => temp.properties.gender);
const filterEleman2 = temps.map(temp => temp.properties.status);
/* making unique array */
let filters1 = [...new Set(filterEleman1)]; //["female", "male"];
let filters2 = [...new Set(filterEleman2)];
/* ------- */
var finalOut = [];
var arrayTemp = [];
function groupFun(key1) {
for(i=0; i<key1.length; i++) {
var keyVal = key1[i][0];
var filt = key1[i][1];
for(j=0; j<keyVal.length; j++) {
var passing = temps.filter(temp => temp.properties[filt] === keyVal[j]);
var countPass = passing.length;
/* "objTemp" and "arrayTemp" are temporary object and array that help to construct final array (finalOut) */
var objTemp = {
key: filt,
value: keyVal[j],
count: countPass
};
arrayTemp.push(objTemp);
}
finalOut.push(arrayTemp);
console.log(finalOut);
arrayTemp = [];
}
}
/* I changed the way that the function is calling */
groupFun([ [filters1, "gender"], [filters2, "status"] ]);
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>array of objects</title>
</head>
<body>
<script src="script.js"></script>
</body>
</html>
I used "filter" and "map" methods of arrays for this question. the ments are added in the script.