Skip to content Skip to sidebar Skip to footer

Javascript: Group Data In Objects

I'm trying to figure out the best way to organize this data in Javascript, so I apologize if this question is broader than usual. I have data: State, Zip 'CA', '945' 'CA', '934' 'M

Solution 1:

I suggest to change the data structure to version with fast access to the state and their Zips.

{"CA":["945","934"],"MA":["934","021","021"]}

To get zips from CA, just take grouped.CA or grouped['CA'].

The solution, you suggested, need always an interation until the data for a state is found. It makes access slow.

var data = [{ State: "CA", Zip: "945" }, { State: "CA", Zip: "934" }, { State: "MA", Zip: "934" }, { State: "MA", Zip: "021" }, { State: "MA", Zip: "021" }],
    grouped = function (array) {
        var r = {};
        array.forEach(function (a) {
            r[a.State] = r[a.State] || [];
            r[a.State].push(a.Zip);
        });
        return r;
    }(data);


document.write('<pre>' + JSON.stringify(grouped, 0, 4) + '</pre>');

Solution 2:

I've created code with sample data. This might be helpful:

vardata = [{
    state: "CA",
    zip: "945"
  },
  {
    state: "CA",
    zip: "934"
  },
  {
    state: "MA",
    zip: "934"
  },
  {
    state: "MA",
    zip: "021"
  },
  {
    state: "MA",
    zip: "021"
  }
];
var zip_mapper = {};

for (var i = 0; i < data.length; i++) {
  if (!zip_mapper[data[i].state]) zip_mapper[data[i].state] = []; //zip codes array
  zip_mapper[data[i].state].push(data[i].zip);
}

// testingfor (var key in zip_mapper) {
  alert(key + "--->" + zip_mapper[key]);
}

Solution 3:

Try this:

vardata = [{
      state: 'CA',
      zip: '945'
    },
    {
      state: 'CA',
      zip: '934'
    },
    {
      state: 'MA',
      zip: '934'
    },
    {
      state: 'MA',
      zip: '021'
    },
    {
      state: 'MA',
      zip: '021'
    },
  ];

  function exists(stateName, data) {
    var existIndex = -1;
    for (var i = 0; i < data.length; i++) {
      if (data[i].state === stateName) {
        existIndex = i;
        break;
      }
    }
    return existIndex;
  }
  var finalData = [],
    index;

  for (var i = 0; i < data.length; i++) {
    index = exists(data[i].state, finalData);
    if (index === -1) {
      finalData.push({
        state: data[i].state,
        zip: []
      })
      finalData[finalData.length - 1].zip.push(data[i].zip)
    } else {
      finalData[index].zip.push(data[i].zip)
    }
  }

  console.log(finalData);

Solution 4:

Here is a way how to do it without a loop, relying on reduce only:

Explanation: Check if element exists in array, if not, then add it to the new acc array, if yes, find the index of that element and add the zip number to the zip array.

Solution

var data = [{
    state: 'CA',
    zip: '945'
  },
  {
    state: 'CA',
    zip: '934'
  },
  {
    state: 'MA',
    zip: '020'
  },
  {
    state: 'MA',
    zip: '021'
  },
  {
    state: 'MA',
    zip: '022'
  },
];

const groupedData = data.reduce((acc, x) => {
  const index = acc.findIndex(y => y.state === x.state);
  if (index < 0) {
    acc.push({
      state: x.state,
      zip: [x.zip]
    });
    return acc;
  }
  acc[index] = {
    ...acc[index],
    state: x.state,
    zip: [...acc[index].zip, x.zip]
  }
  return acc;
}, [])

console.log(groupedData)

Post a Comment for "Javascript: Group Data In Objects"