0

I have a large object of arrays. I need to break down this object into an array of objects. I believe that underscore.js is good tool for this type of object transformation, but I’ve never used that library before. For this example I need to convert the key of each property to a ‘name’ variable in the output array, and than push elements of each property of each object into array's. That’s difficult to explain so below I have a before and after array to help visualize what I’m trying to accomplish. Can I accomplish this task with underscore.js easier than pure javascript ? I’ve attempted this with for loops and if else statements but it got messy quickly, so any help is greatly appreciated.

Before:

var obj = {
    "AH5T5TAFXX-001": 
        ["AH5T5TAFXX-001",
        {
            Bin_reads:2436307,
            IC_lot:1,
            LabChip_size_bp:410,
            LibType:"RNA",
            Tot_reads:7386376,
            bioSple:193,
            internal_controls:5
        }, {
            Bin_reads:2906003,
            IC_lot:1,
            LabChip_size_bp:395,
            LibType:"RNA",
            Tot_reads:6680167,
            bioSple:198,
            internal_controls:5
        }],
    "AH5NVVAFXX-002":
        ["AH5NVVAFXX-002",
        {   
            Bin_reads:2436307,
            IC_lot:1,
            LabChip_size_bp:410,
            LibType:"RNA",
            Tot_reads:7386376,
            bioSple:193,
            internal_controls:5
        },
        {   
            Bin_reads:2436307,
            IC_lot:1,
            LabChip_size_bp:410,
            LibType:"RNA",
            Tot_reads:6680167,
            bioSple:193,
            internal_controls:5
        }]
};

After:

var arr = [
    {
        "name": "AH5T5TAFXX-001",
        "Bin_reads": [2436307,2906003],
        "IC_lot": [1,1],
        "LabChip_size_bp": [410,395],
        "LibType": ["RNA", "RNA"],
        "Tot_reads": [7386376,6680167]
        "bioSple": [193,198],
        "internal_controls": [5,5]
    },{
        "name": "AH5T5TAFXX-002",
        "Bin_reads": [2436307,2906003],
        "IC_lot": [1,1],
        "LabChip_size_bp": [410,395],
        "LibType": ["RNA", "RNA"],
        "Tot_reads": [7386376,6680167]
        "bioSple": [193,198],
        "internal_controls": [5,5]
    }
];

4 Answers 4

1

The following is a robust method to flatten your data structure and merge the individual entries. It is agnostic to the number and order of entries:

var result = Object.keys(obj).map((key, index) => {
  var entries = obj[key];
  var combined = {};
  entries.forEach(entry => {
    if (typeof entry === 'string') {
       combined.name = entry;
    } else {
      Object.keys(entry).forEach(key => {
        if (Array.isArray(combined[key])) {
          combined[key].push(entry[key]);
        } else {
          combined[key] = [entry[key]];
        }
      });
    }
  });
  return combined;
})

var obj = {
    "AH5T5TAFXX-001": 
        ["AH5T5TAFXX-001",
        {
            Bin_reads:2436307,
            IC_lot:1,
            LabChip_size_bp:410,
            LibType:"RNA",
            Tot_reads:7386376,
            bioSple:193,
            internal_controls:5
        }, {
            Bin_reads:2906003,
            IC_lot:1,
            LabChip_size_bp:395,
            LibType:"RNA",
            Tot_reads:6680167,
            bioSple:198,
            internal_controls:5
        }],
    "AH5NVVAFXX-002":
        ["AH5NVVAFXX-002",
        {   
            Bin_reads:2436307,
            IC_lot:1,
            LabChip_size_bp:410,
            LibType:"RNA",
            Tot_reads:7386376,
            bioSple:193,
            internal_controls:5
        },
        {   
            Bin_reads:2436307,
            IC_lot:1,
            LabChip_size_bp:410,
            LibType:"RNA",
            Tot_reads:6680167,
            bioSple:193,
            internal_controls:5
        }]
};

var result = Object.keys(obj).map((key, index) => {
  var entries = obj[key];
  var combined = {};
  entries.forEach(entry => {
    if (typeof entry === 'string') {
      combined.name = entry;
    } else {
      Object.keys(entry).forEach(key => {
        if (Array.isArray(combined[key])) {
          combined[key].push(entry[key]);
        } else {
          combined[key] = [entry[key]];
        }
      });
    }
  });
  return combined;
})

console.log(result);

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

Comments

1
// iterate through the keys of 'obj'
// create an array element for each key
console.log( Object.keys(obj).map( function(key){ 

  // 'result' is the element to be returned for each key
  // every property value of 'obj' is an array
  // whose first element represents the name of the new object
  var result = {
    'name': obj[key][0]
  };
  if( obj[key].length > 1 ){
      // pull all attribute names of second element of array
      // and set them to empty arrays in the transformed object
      var properties = Object.keys( obj[key][1] );
      properties.forEach( function( prop ){ result[prop] = []; } );

      // iterate through the input array (skipping the first element)
      // and add a value to the matching array of 'result' 
      for( var i=1; i<obj[key].length; i++ )
        properties.forEach( function( prop ){ result[prop].push( obj[key][i][prop] ); } );
    }
    return result;

}) );

2 Comments

I'm confused on how to use this.. what is the output array? leaving code with no description is not good practice
How does this generate an output array? again some description would be great
0

This function:

function solution(A)
{
    var result = [];
    for (var key in A)
    {
        var subArr = A[key];

        var newObj = {};
        result.push(newObj);
        newObj.name = key;

        for (var i=1, ii=subArr.length; i<ii; i++)
        {
            var subSubObj = subArr[i];
            for (var subSubKey in subSubObj)
            {
                if (!newObj[subSubKey])
                    newObj[subSubKey] = [subSubObj[subSubKey]];
                else
                    newObj[subSubKey].push(subSubObj[subSubKey]);
            }
        }
    }

    return result;
}

will return this object if given your input:

[
    {
        "name": "AH5T5TAFXX-001",
        "Bin_reads": [2436307,2906003],
        "IC_lot": [1,1],
        "LabChip_size_bp": [410,395],
        "LibType": ["RNA","RNA"],
        "Tot_reads": [7386376,6680167],
        "bioSple": [193,198],
        "internal_controls": [5,5]
    },
    {
        "name": "AH5NVVAFXX-002",
        "Bin_reads": [2436307,2436307],
        "IC_lot": [1,1],
        "LabChip_size_bp": [410,410],
        "LibType": ["RNA","RNA"],
        "Tot_reads": [7386376,6680167],
        "bioSple": [193,193],
        "internal_controls": [5,5]
    }
]

JSFiddle example (logs to console, so open dev tools): https://jsfiddle.net/mpey5wfv/

Comments

0

In a very very straight forward way, it'd look like this:

// output array
var arr = [];

// iterating the "obj" object
for (prop1 in obj) {

    // temporary object
    var newObj = {
        // setting the property name
        name : prop1,
    };

    // iterating the array of objects
    // skipping the first item. it is a string
    for (var i = 1; i < obj[prop1].length; i++) {

        // iterating the object that's inside the array
        for (prop2 in obj[prop1][i]) {

            // checking if the new property already exists in the new obj
            // if not, create it
            if (!newObj[prop2]) {
                newObj[prop2] = [];
            }

            // adding the values from the two objects into an array in a single object
            newObj[prop2].push(obj[prop1][i][prop2]);
        }
    }
    arr.push(newObj);
}

console.log(JSON.stringify(arr, false, "\t")) outputs

[
    {
        "name": "AH5T5TAFXX-001",
        "Bin_reads": [
            2436307,
            2906003
        ],
        "IC_lot": [
            1,
            1
        ],
        "LabChip_size_bp": [
            410,
            395
        ],
        "LibType": [
            "RNA",
            "RNA"
        ],
        "Tot_reads": [
            7386376,
            6680167
        ],
        "bioSple": [
            193,
            198
        ],
        "internal_controls": [
            5,
            5
        ]
    },
    {
        "name": "AH5NVVAFXX-002",
        "Bin_reads": [
            2436307,
            2436307
        ],
        "IC_lot": [
            1,
            1
        ],
        "LabChip_size_bp": [
            410,
            410
        ],
        "LibType": [
            "RNA",
            "RNA"
        ],
        "Tot_reads": [
            7386376,
            6680167
        ],
        "bioSple": [
            193,
            193
        ],
        "internal_controls": [
            5,
            5
        ]
    }
]

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.