最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Group by the array of objects based on the property and also the count in javascript - Stack Overflow

programmeradmin0浏览0评论

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
Add a ment  | 

4 Answers 4

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.

发布评论

评论列表(0)

  1. 暂无评论