1

I want to merge the last keys that can be any random string of all the objects in the array if the fname and address is same. To give more context, I need this format to draw a graph with recharts.

const data = [
  {
    fname: "adam",
    address: "us",
    key1: 12
  },
  {
    fname: "adam",
    address: "us",
    key2: 31
  },
  {
    fname: "adam",
    address: "uk",
    qwe: 41
  },
  {
    fname: "Dan",
    address: "au",
    asd: 31
  },
  {
    fname: "Dan",
    address: "au",
    zxc: 31
  },
  {
    fname: "Chris",
    address: "nz",
    randomkey: 12 
  },
  {
    fname: "Chris",
    address: "br",
    randomkey2: 14 
  },
];

This should return something like

const data = [
  {
    fname: "adam",
    address: "us",
    key1: 12,
    key2: 31
  },
  {
    fname: "adam",
    address: "uk",
    qwe: 41
  },
  {
    fname: "Dan",
    address: "au",
    asd: 31,
    zxc: 31
  },
  {
    fname: "Chris",
    address: "nz",
    randomkey: 12 
  },
  {
    fname: "Chris",
    address: "br",
    randomkey2: 14 
  },
];
2
  • 1
    How do you want to handle key collisions? Commented Mar 12, 2020 at 19:58
  • The array of objects I have, the random keys will always be unique. Commented Mar 12, 2020 at 20:05

4 Answers 4

3

Using a very naive approach, you could create a hash map to collect the unique name + address, then iterate over the map. Something like this:

const data = [{}, {}, {}] //...data in question
var map = {};
data.forEach(function(item) {
  var id = item.fname + "|" + item.address; // | cannot occur in address or name
  if (map[id] === undefined) {
    map[id] = item;
  } else {
    var existing = map[id]; // adding/updating new keys
    for (var propt in item) {
      existing[propt] = item[propt];
    }
  }
});
var results = [];
Object.keys(map).forEach(k => results.push(map[k]));

Then results should hold your processed data

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

2 Comments

Initial version was actually not getting what op asked. Now it should work. One open point is that this implementation will use the last value of a given key when repeated address+names are there.
Thanks, this works. I edited it a bit but it works. Cheers
2

const data = [
  {
    fname: "adam",
    address: "us",
    key1: 12
  },
  {
    fname: "adam",
    address: "us",
    key2: 31
  },
  {
    fname: "adam",
    address: "uk",
    qwe: 41
  },
  {
    fname: "Dan",
    address: "au",
    asd: 31
  },
  {
    fname: "Dan",
    address: "au",
    zxc: 31
  },
  {
    fname: "Chris",
    address: "nz",
    randomkey: 12 
  },
  {
    fname: "Chris",
    address: "br",
    randomkey2: 14 
  },
]
const result=[]
data.forEach((obj,index)=>{
    let found=false;
	index===0?result.push(obj):result.forEach((obj2,index2)=>{
		if(obj2.fname===obj.fname&&obj2.address===obj.address){
    		result[index2]={...obj,...obj2}
            found=true;
            }
       })
       found===false&&index!==0&&result.push(obj)
})
console.log(result)

I know it's already been answered but I found it interesting to solver

Comments

2

You could take an object with some properties from data as keys for collecting the objects.

const
    data = [{ fname: "adam", address: "us", key1: 12 }, { fname: "adam", address: "us", key2: 31 }, { fname: "adam", address: "uk", qwe: 41 }, { fname: "Dan", address: "au", asd: 31 }, { fname: "Dan", address: "au", zxc: 31 }, { fname: "Chris", address: "nz", randomkey: 12  }, { fname: "Chris", address: "br", randomkey2: 14 }],
    keys = ['fname', 'address'],
    result = Object.values(data.reduce((r, o) => {
        var key = keys.map(k => o[k]).join();
        Object.assign(r[key] =  r[key] || {}, o);
        return r;
    }, {}));

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

Comments

1

The code is kind of complex. But it works fine.

/* DATA */
const data=[{fname:"adam",address:"us",key1:12},{fname:"adam",address:"us",key2:31},{fname:"adam",address:"uk",qwe:41},{fname:"Dan",address:"au",asd:31},{fname:"Dan",address:"au",zxc:31},{fname:"Chris",address:"nz",randomkey:12},{fname:"Chris",address:"br",randomkey2:14}];

/* ATTEMPT TO GET THE RESULT */
var temp = {};
for(var k in data){

  // finding the random key and random value
  var randkey, randvalue;
  for(var rk in data[k]){
    if(rk != 'fname' && rk != 'address'){
      randkey = rk;
      randvalue = data[k][rk];
    }
  }

  // getting fname and address
  var fname = data[k].fname;
  var address = data[k].address;

  // adding this data into the 'temp' object with the fname|address (if not exists already)
  // if exists then add the key only
  var unify = fname + '|' + address;
  if( !temp[unify] ){
    temp[unify] = {};
    temp[unify].fname = fname;
    temp[unify].address = address;
    temp[unify][randkey] = randvalue;
  }else{
    temp[unify][randkey] = randvalue;
  }

}


// getting the result array from temp
var result = [];
for(var k in temp ){
  result.push(temp[k]);
}

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

1 Comment

Thanks for your help!

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.