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!

1

3 Answers 3

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)

Sign up to request clarification or add additional context in comments.

Comments

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);

2 Comments

This is a very interesting solution.
@Kinduser Could probably be improved by substituting passing parameters to function rather than hard coding properties within both fn and props functions
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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.