Search code examples
javascriptarraysexport-to-csv

Object transformation assistance


I have a list of single key value pairs, where the key is a 2 part string that describes where the value should be plotted on a table. This is the first time I've asked a questions on SO so please go easy on me.

let tiles = [
  { 'A~baz': 'x' },
  { 'A~buzz': 'o' },
  { 'A~fam': '' },
  { 'B~baz': 'x' },
  { 'B~buzz': '' },
  { 'B~fam': '' },
  { 'C~baz': 'x' },
  { 'C~buzz': 'x' },
  { 'C~fam': 'x' }
]

I want to convert it into the below format.

[
  { _id: 'A', baz: 'x', buzz: 'o', fam: '' },
  { _id: 'B', baz: 'x', buzz: '', fam: '' },
  { _id: 'C', baz: 'x', buzz: 'x', fam: 'x' }
]

Note I will need to perform this operation on hundreds of thousands of key value pairs.

What I have done so far, this works, but I was hoping there could be places I can make improvements.

let tiles = [
  { 'C~fam': "x" },  
  { 'B~buzz': "" },
  { 'B~fam': "" },
  { 'A~fam': "" },
  { 'A~buzz': "o" },
  { 'B~baz': "x" },
  { 'A~baz': "x" },
  { 'C~baz': "x" },
  { 'C~buzz': "x" },
];

// I thought it would help to sort the array
tiles.sort((a, b) => Object.keys(a)[0].localeCompare(Object.keys(b)[0]));

let obj = {};
tiles.forEach((kvp) => { //kvp = key value pair
  let [row,col] = Object.keys(kvp)[0].split('~') //destruct by '~'
  let val = Object.values(kvp)[0];
  obj[row] = obj[row] ?? {} 
  obj[row][col] = val;
})

let keys = Object.keys(obj);
let values = Object.values(obj)

let output = [];
for (let i = 0, len = keys.length; i < len; i++) {
  output.push(Object.assign({_id : `${keys[i]}`}, values[i]));
}

Solution

  • Here you've got single loop solution

    let res = {};
    let arrayRes = [];
    tiles.forEach(function(tile) {
        let tileKey = Object.keys(tile)[0];
        let tileKeySplitted = tileKey.split('~');
        let column = tileKeySplitted[0];
        let key = tileKeySplitted[1];
        if (res[column] == null) {
            res[column] = {'_id': column};
            arrayRes.push(res[column]);
        }
        res[column][key] = tile[tileKey];
    });
    console.log(arrayRes);