0

I want to merge a single array of multiple objects dynamically with the same key. An example of the data is this:

var data = [{
  ReportTime: "30 Apr 2017BDT",
  Rate: "1.00000",
  AvgGrowth: "0.0"
}, {
  ReportTime: "30 Apr 2017BDT",
  Rate: "0.01107",
  AvgGrowth: "0.1"
}, {
  ReportTime: "29 Apr 2017BDT",
  Rate: "1.00000",
  AvgGrowth: "0.0"
}, {
  ReportTime: "29 Apr 2017BDT",
  Rate: "0.01107",
  AvgGrowth: "-0.5"
}]

I want to generate data like this

newData = [{
  "30 Apr 2017BDT",
  "1.00000",
  "0.0",
  "0.01107",
  "0.1"
}, {
  "29 Apr 2017BDT",
  "1.00000",
  "0.0",
  "0.01107",
  "-0.5"
}];

I need a suggestion or help how can I resolve this issue.

6
  • what is the key and what is your criteria to merge? Commented Apr 8, 2020 at 9:17
  • Key is ReportTime when we find the same Report time we need to merge that object Commented Apr 8, 2020 at 9:18
  • The data structure you're trying to create is invalid as the properties in the objects have no value. Commented Apr 8, 2020 at 9:19
  • @RoryMcCrossan Okay, can you please let me know how can I merge two objects with the same property name in a single array? Commented Apr 8, 2020 at 9:21
  • why is rate and avg growth not merged in your output? They are just new properties.. Commented Apr 8, 2020 at 9:22

3 Answers 3

1

Your expected output doesn't looks a valid JS. You can however get an array of arrays by iterating over the array using a couple of methods like .reduce(), .map() and Object.entries():

const data = [
  {ReportTime: "30 Apr 2017BDT", Rate: "1.00000", AvgGrowth: "0.0"},
  {ReportTime: "30 Apr 2017BDT", Rate: "0.01107", AvgGrowth: "0.1"},
  {ReportTime: "29 Apr 2017BDT", Rate: "1.00000", AvgGrowth: "0.0"},
  {ReportTime: "29 Apr 2017BDT", Rate: "0.01107", AvgGrowth: "-0.5"}
];

const result = Object.entries(
  data.reduce((r, {ReportTime, ...rest}) => {
    r[ReportTime] = (r[ReportTime] || []).concat(Object.values(rest));
    return r;
  }, {})
).map(([k, v]) => [k, ...v]);

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

Here is an alternate approach which uses es5(old) syntax:

var data = [
  {ReportTime: "30 Apr 2017BDT", Rate: "1.00000", AvgGrowth: "0.0"},
  {ReportTime: "30 Apr 2017BDT", Rate: "0.01107", AvgGrowth: "0.1"},
  {ReportTime: "29 Apr 2017BDT", Rate: "1.00000", AvgGrowth: "0.0"},
  {ReportTime: "29 Apr 2017BDT", Rate: "0.01107", AvgGrowth: "-0.5"}
];
var key = 'ReportTime';

var reducer = function(data, key) {
  var result = [];
  var map = {};
  
  data.forEach(function(o, i) {
    map[o[key]] = map[o[key]] || [];
    
    for(var k in o) {
      if(!(k === key)) { map[o[key]].push(o[k]); }
    };
  });
  
  for(var j in map) {
    result.push([].concat(j, map[j]));
  };
  
  return result;
};

console.log(reducer(data, key));

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

2 Comments

This is what exactly I want as the solution but gives me an error Property 'values' does not exist on type 'ObjectConstructor'.
@ParthRaval Are you using typescript? If yes then here is the answer.. stackoverflow.com/questions/52304422/…
1

You can use reduce to group values by ReportTime

const data = [{ ReportTime: "30 Apr 2017BDT", Rate: "1.00000", AvgGrowth: "0.0"}, { ReportTime: "30 Apr 2017BDT", Rate: "0.01107", AvgGrowth: "0.1"}, { ReportTime: "29 Apr 2017BDT", Rate: "1.00000", AvgGrowth: "0.0"
}, { ReportTime: "29 Apr 2017BDT", Rate: "0.01107", AvgGrowth: "-0.5"}]

const merged = data.reduce((op, inp) => {
  let key = inp.ReportTime
  op[key] = op[key] || []
  op[key].push(inp)
  return op
}, Object.create(null))

console.log(merged)

Comments

1

I think if make group ReportTime's into object with maintaining Rate and AvgGrowth will be helpful.

Go over items, Build an object with keys as "ReportTime". When ReportTime already exist in object, just update the Rate and AvgGrowth. After the iteration, Get Object.values() of above object to get it as array.

const update = data => {
  const res = {};
  data.forEach(item => {
    if (!res[item.ReportTime]) {
      res[item.ReportTime] = {
        ReportTime: item.ReportTime,
        Rate: [],
        AvgGrowth: []
      };
    }
    res[item.ReportTime].Rate.push(item.Rate);
    res[item.ReportTime].AvgGrowth.push(item.AvgGrowth);
  });
  return Object.values(res);
};

var data = [
  {
    ReportTime: "30 Apr 2017BDT",
    Rate: "1.00000",
    AvgGrowth: "0.0"
  },
  {
    ReportTime: "30 Apr 2017BDT",
    Rate: "0.01107",
    AvgGrowth: "0.1"
  },
  {
    ReportTime: "29 Apr 2017BDT",
    Rate: "1.00000",
    AvgGrowth: "0.0"
  },
  {
    ReportTime: "29 Apr 2017BDT",
    Rate: "0.01107",
    AvgGrowth: "-0.5"
  }
];

console.log(update(data));

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.