1

I need to display some data on a grid but in a different format than I am fetching it in and having a difficult time figuring out how to refactor it. I am grabbing a set of javascript objects which contain a subscription length and a price along with other details. All objects whose values in the other columns are a match, should be combined into 1 object. The new object should have the same columns which the old items had except for subscription length and price. These should become key value pairs on the new object. An example:

[
{
col_a:"value",
col_b:"foo",
col_c: true,
subscription_length:3,
price:10
},
{
col_a:"value",
col_b:"foo",
col_c: true,
subscription_length:6,
price:18
},
{
col_a:"value",
col_b:"foo",
col_c: true,
subscription_length:12,
price:32
},
{
col_a:"something",
col_b:"bar",
col_c: false,
subscription_length:3,
price:8
},
{
col_a:"something",
col_b:"bar",
col_c: false,
subscription_length:6,
price:15
},
{
col_a:"something",
col_b:"bar",
col_c: false,
subscription_length:12,
price:28
}
]

would become:

[
{
col_a:"value",
col_b:"foo",
col_c: true,
3:10,
6:18,
12:32
},
{
col_a:"something",
col_b:"bar",
col_c: false,
3:8,
6:15,
12:28
}
]

I assume I can use a map function possibly with a reduce, but I don't know where to start. Thanks for any and all pointers!

  • Possible duplicate of [Access / process (nested) objects, arrays or JSON](http://stackoverflow.com/questions/11922383/access-process-nested-objects-arrays-or-json) – Teemu Mar 18 '17 at 21:07

3 Answers3

1

You were on the right track; I used a combination of Array#reduce, Array#map, and Object.keys:

var data = [{
    col_a: "value",
    col_b: "foo",
    col_c: true,
    subscription_length: 3,
    price: 10
  },
  {
    col_a: "value",
    col_b: "foo",
    col_c: true,
    subscription_length: 6,
    price: 18
  },
  {
    col_a: "value",
    col_b: "foo",
    col_c: true,
    subscription_length: 12,
    price: 32
  },
  {
    col_a: "something",
    col_b: "bar",
    col_c: false,
    subscription_length: 3,
    price: 8
  },
  {
    col_a: "something",
    col_b: "bar",
    col_c: false,
    subscription_length: 6,
    price: 15
  },
  {
    col_a: "something",
    col_b: "bar",
    col_c: false,
    subscription_length: 12,
    price: 28
  }
]

var map = data.reduce(function(map, e) {
  var k = [e.col_a, e.col_b, e.col_c].join()
  if (!map[k]) map[k] = {
    col_a: e.col_a,
    col_b: e.col_b,
    col_c: e.col_c
  }
  map[k][e.subscription_length] = e.price
  return map
}, {})

var result = Object.keys(map).map(function(k) { return this[k] }, map)

console.log(result)
gyre
  • 16,369
  • 3
  • 37
  • 47
1

You can use Array.prototype.filter(), Array.prototype.reduce(), Object.assign()

var data = [{
    col_a: "value",
    col_b: "foo",
    col_c: true,
    subscription_length: 3,
    price: 10
  },
  {
    col_a: "value",
    col_b: "foo",
    col_c: true,
    subscription_length: 6,
    price: 18
  },
  {
    col_a: "value",
    col_b: "foo",
    col_c: true,
    subscription_length: 12,
    price: 32
  },
  {
    col_a: "something",
    col_b: "bar",
    col_c: false,
    subscription_length: 3,
    price: 8
  },
  {
    col_a: "something",
    col_b: "bar",
    col_c: false,
    subscription_length: 6,
    price: 15
  },
  {
    col_a: "something",
    col_b: "bar",
    col_c: false,
    subscription_length: 12,
    price: 28
  }
]

let fn = (arr, prop) => arr.filter(({col_a}) => col_a === prop);

let props = curr => curr.reduce((o, prop) => Object.assign(o, {
  [prop.subscription_length]: prop.price,
  col_a: prop.col_a,
  col_b: prop.col_b,
  col_c: prop.col_c
}), {});

let res = Array.of(props(fn(data, "value")), props(fn(data, "something")));

console.log(res);
guest271314
  • 1
  • 15
  • 104
  • 177
0

Took a while but I've experienced few errors. I'm aware that it's not as good as the previous answers, but still it works fine.

var data = [{ col_a: "value", col_b: "foo", col_c: true, subscription_length: 3, price: 10 }, { col_a: "value", col_b: "foo", col_c: true, subscription_length: 6, price: 18 }, { col_a: "value", col_b: "foo", col_c: true, subscription_length: 12, price: 32 }, { col_a: "something", col_b: "bar", col_c: false, subscription_length: 3, price: 8 }, { col_a: "something", col_b: "bar", col_c: false, subscription_length: 6, price: 15 }, { col_a: "something", col_b: "bar", col_c: false, subscription_length: 12, price: 28 }], 
    result = [], 
    ss = [...new Set(data.map(v => v.col_a))];

    ss.forEach(function(v){
      var obj = {};
      obj.col_a = v;
      obj.col_b = data.find(x => x.col_a == v).col_b;
      obj.col_c = data.find(z => z.col_a == v).col_c;
      data.forEach(function(c){
        if (c.col_a == v){
          obj[c.subscription_length] = c.price;
        }
      });
      result.push(obj);
    });
    
    console.log(result);
kind user
  • 40,029
  • 7
  • 67
  • 77