spoike
5/6/2014 - 2:45 PM

Handling irregular objects in an array, where inspecting chain may lead to TypeErrors due to undefined values. Useful on REST API's that fo

Handling irregular objects in an array, where inspecting chain may lead to TypeErrors due to undefined values.

Useful on REST API's that for some reason returns irregular objects in an array.

Testcase

An array of cats and dogs

var catsAndDogsArr = [ 
  { 
    cat: { 
      name: 'Arya' 
    } 
  },
  { 
    cat: { 
      name: 'Ser Pounce' 
    } 
  }, 
  { 
    dog: { 
      name: 'The Hound' 
    } 
  } 
];

Usage

Use it in lodash as usual:

_.pluckRef(catsAndDogsArr, 'cat.name');
// -> ["Arya", "Ser Pounce"]
_.pluckRef(catsAndDogsArr, 'dog.name');
// -> ["The Hound"]

Or use lodash's chaining facility if you need to handle the data coming out of pluckRef:

_(catsAndDogsArr).pluckRef('cat.name').value();
// -> ["Arya", "Ser Pounce"]
_(catsAndDogsArr).pluckRef('dog.name').value();
// -> ["The Hound"]
// Adds pluckRef method to lodash
// Example: _.(array, 'key1.key2.key3');
// Goes through each object of the array and attempts to pluck objects that are
// in the specified object chain path. It filters away undefined values.
_.mixin({
    'pluckRef': function(arr, keyPathRef) {
        var i, j, keys, key, ref, output = [];
        keys = keyPathRef.split('.');
        
        // for each object in the array
        for (i = 0; i < arr.length; i++) {
            ref = arr[i];
            // for each key in keyPathRef
            for (j = 0; j < keys.length; j++) {
                key = keys[j];
                // reduce reference to the next key
                ref = ref[key];
                // if undefined value is hit, break the loop
                if (typeof ref === 'undefined') {
                    break;
                }
            }
            // if undefined continue to the next
            if (typeof ref === 'undefined') {
                continue;
            }
            // else valid value is pushed to the output
            output.push(ref);
        }
        return output;
    }
});