Fernando Vega
Fernando Vega

Reputation: 527

Transform an array of Objects to a new set of Object using javascript?

This question has been asked in many different forms, but I haven't been able to piece it all together to achieve the outcome I'm looking for. So, sorry for duplicating the duplicates...

What I'm wanting to do is take an Array like this:

[
  0: { 
       2014: "6", 
       2015: "19",
       2016: "3",
       2017: "12",
       Name: "Jerry"
     },
  1: { 
       2014: "16", 
       2015: "9",
       2016: "",
       2017: "16",
       Name: "Bill"
     },
  2: { 
       2014: "", 
       2015: "2",
       2016: "43",
       2017: "7",
       Name: "Grace"
     }
]

Into something like this:

{
    "years": {
        "2014": {
            "Jerry": 6,
            "Bill": 16,
            "Grace": ""
        },
        "2015": {
            "Jerry": 19,
            "Bill": 9,
            "Grace": 2
        },
        "2016": {
            "Jerry": 3,
            "Bill": "",
            "Grace": 43
        },
        "2017": {
            "Jerry": 12,
            "Bill": 16,
            "Grace": 7
        }
    }
}

Bit of Code I still have after trying stuff, deleting, repeat, repeat...:

FYI - data is from CSV file being loaded from D3.js csv()

let loadData = () => {
    return d3.csv(dataFile, function cb (err, d) {
        if (err) throw err;
        return d;
    });
};

loadData().get((err, n) => {
    if (err) throw err;

    let years = [];

    years.push(Object.keys(n[0]));

    years = _.flatten(years);
    years.splice(-1, 1);


    console.log(n[0]);

    n.map((x) => {
        console.log(Object.keys(x[0]));
    });

});

Upvotes: 0

Views: 69

Answers (5)

kuroi neko
kuroi neko

Reputation: 8661

reduce is not mandatory. For instance:

let result = { years : {} };
for (let record of input) {
    for (let key in record) {
        if (key == 'Name') continue;
        result.years[key] = result.years[key] || {};
        result.years[key][record.Name] = record[key];
    }
}

Upvotes: 0

ajai Jothi
ajai Jothi

Reputation: 2294

You can use Array.prototype.reduce method for this scenario. First parameter to this method is a reducer and the second one is initial value.

var input = [{
    2014: "6",
    2015: "19",
    2016: "3",
    2017: "12",
    Name: "Jerry"
  },
  {
    2014: "16",
    2015: "9",
    2016: "",
    2017: "16",
    Name: "Bill"
  },
  {
    2014: "",
    2015: "2",
    2016: "43",
    2017: "7",
    Name: "Grace"
  }
];

var output = input.reduce((a, b) => {
  for (var k in b) {
    if (k !== 'Name') {
      a.year[k] = a.year[k] || {};
      a.year[k][b.Name] = b[k];
    }
  }
  return a;
}, {
  years: {}
});

console.log(output);

Upvotes: 0

Nenad Vracar
Nenad Vracar

Reputation: 122047

You can use reduce() to build object and inside you can use Object.keys() and forEach() loop to add object for each year.

var arr = [{"2014":"6","2015":"19","2016":"3","2017":"12","Name":"Jerry"},{"2014":"16","2015":"9","2016":"","2017":"16","Name":"Bill"},{"2014":"","2015":"2","2016":"43","2017":"7","Name":"Grace"}]

var result = arr.reduce(function(r, o) {
  Object.keys(o).forEach(function(e) {
    if(!r.years[e]  && e != 'Name') r.years[e] = {}
    Object.assign(r.years[e] || {}, {[o.Name]: o[e]})
  })
  return r;
}, {years: {}})

console.log(JSON.stringify(result, 0, 4))

Upvotes: 0

blackmiaool
blackmiaool

Reputation: 5344

You can use "reduce" to achieve this.

var data = [{
  2014: "6",
  2015: "19",
  2016: "3",
  2017: "12",
  Name: "Jerry"
}, {
  2014: "16",
  2015: "9",
  2016: "",
  2017: "16",
  Name: "Bill"
}, {
  2014: "",
  2015: "2",
  2016: "43",
  2017: "7",
  Name: "Grace"
}];

data = data.reduce(function(pre, v) {

  for (var i in v) {
    if (i === 'Name') {
      continue;
    }
    if (!pre[i]) {
      pre[i] = {};
    };

    pre[i][v.Name] = v[i];

  }
  return pre;
}, {});
data = {
  years: data
};
console.log(data);

Upvotes: 2

Nina Scholz
Nina Scholz

Reputation: 386578

You could iterating the array and the keys and build a new object.

var data = [{ 2014: "6", 2015: "19", 2016: "3", 2017: "12", Name: "Jerry" }, { 2014: "16", 2015: "9", 2016: "", 2017: "16", Name: "Bill" }, { 2014: "", 2015: "2", 2016: "43", 2017: "7", Name: "Grace" }],
    grouped = { years: {} };

data.forEach(function (o) {
    Object.keys(o).forEach(function (k) {
        if (k !== 'Name') {
            grouped.years[k] = grouped.years[k] || {};
            grouped.years[k][o.Name] = o[k];
        }
    });
});

console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

Related Questions