ang
ang

Reputation: 1581

How to Group Array by Property and Reindex Result

I am trying to group items an array of items by a property and then reindex the result starting from 0.

The following function returns a grouped set of items.

groupItemBy(array, property) {
  let hash = {},
  props = property.split('.');
    for (let i = 0; i < array.length; i++) {
      let key = props.reduce( (acc, prop) => {
        return acc && acc[prop];
      }, array[i]);
      if (!hash[key]) hash[key] = [];
        hash[key].push(array[i]);
      }
      return hash;
}

The result is an array of arrays, and something like:

[{
  "1193312":[
    {
      "description":"Item 1",
      "number": "1193312"
    }
  ],
  "1193314":[
    {
      "itemDesc":"Item 2"},
      "number": "1193314"
    {
      "description":"Item 3",
      "number": "1193314"
    }
  ],
  etc...
}]

From here I'd like to map 1193312 to 0, and 1193314 to 1, etc.

I tried .filter(val => val) on the result, but that seemed to have no effect.

Upvotes: 2

Views: 136

Answers (4)

Keith
Keith

Reputation: 24211

You could use map for the array part, and Object.values and reduce for the renumber part.

const data = [{
  "1193312":[
    {
      "time":"2018-02-20",
      "description":"Item 1",
      "number": "1193312"
    }
  ],
  "1193314":[
    {
      "time":"2018-02-21",
      "itemDesc":"Item 2",
      "number": "1193314"
    },{
      "time":"2018-02-21",
      "description":"Item 3",
      "number": "1193314"
    }
  ]
}];

const renumbered =
  data.map((m) => Object.values(m).reduce((a,v,ix) => (a[ix] = v, a), {}));
  
console.log(renumbered);

Upvotes: 2

stdob--
stdob--

Reputation: 29172

You need to use an intermediate key replacement:

function groupItemBy(array, property) {
  let hash = {}
  let props = property.split('.')
  let keys = []

  for (let i = 0; i < array.length; i++) {
    let key = props.reduce((acc, prop) => {
      return acc && acc[prop];
    }, array[i]);
    let subst = keys.indexOf(key)
    if (subst === -1) {
        keys.push(key)
        subst = keys.length - 1
    }
    if (!hash[subst]) hash[subst] = [];
    hash[subst].push(array[i]);
  }
  return hash;
}

[ https://jsfiddle.net/05t9141p/ ]

Upvotes: 2

Vladu Ionut
Vladu Ionut

Reputation: 8193

var data = [{
  "1193312":[
    {
      "description":"Item 1",
      "number": "1193312"
    }
  ],
  "1193314":[
    {
      "itemDesc":"Item 2",
      "number": "1193314"},
    {
      "description":"Item 3",
      "number": "1193314"
    }
  ]
}]
var newData = Object.keys(data[0]).map(function(key,index){
var newObj={};
newObj[index] = data[0][key];
return newObj;
});
console.log(newData);

Upvotes: 1

Faly
Faly

Reputation: 13356

If you can use ES6:

var arr = [{
  "1193312":[
    {
      "time":"2018-02-20",
      "description":"Item 1"
    }
  ],
  "1193314":[
    {
      "time":"2018-02-21",
      "itemDesc":"Item 2"}, 
    {
      "time":"2018-02-21",
      "description":"Item 3"
    }
  ]
}];
var data = arr[0];
var res = Object.entries(data).map(([key, value]) => ({[key]: value}));
console.log(res);

Upvotes: 0

Related Questions