0

I want to transform this to an array of objects ordered based on an array of keys:

{
  tom: 11,
  jim: 22,
  jay: 13
}

Input -> Output examples:

['jim', 'tom', 'kim', 'jay'] -> [{jim: 22}, {tom: 11}, {jay: 13}]

['may', 'jay', 'tom', 'jim'] -> [{jay: 13}, {tom: 11}, {jim: 22}]

How can I accomplish this? I'd rather a one line lodash solution.

David Henry
  • 101
  • 1
  • 7

4 Answers4

0

For what it is worth, here's a JS function that performs what you want.

function transform(targetObj, keyArray) {
    let resultArray = [];

    // Sanity (may want to throw error here)
    if (!targetObj || !keyArray) { return resultArray; }

    for (let i = 0; i < keyArray.length; i++) {
        if (!targetObj.hasOwnProperty(keyArray[i])) { continue; }     
        let item = {};
        item[keyArray[i]] = targetObj[keyArray[i]];
        resultArray.push(item);
    }

    return resultArray;   
}

Tests

let obj = { tom: 11, jim: 22, jay: 13 };
let input1 = ['jim', 'tom', 'kim', 'jay'];
let input2 = ['may', 'jay', 'tom', 'jim'];

let result1 = transform(obj, input1);
console.log(JSON.stringify(result1));

let result2 = transform(obj, input2);
console.log(JSON.stringify(result2)); 

JSFiddle

gcaton
  • 91
  • 6
0

Assuming the object is named obj and the list of keys to look up is named keys:

_.zip([keys, keys.map(x => obj[x])]).filter(([k, v]) => v).map(x => _.fromPairs([x]))

Or, if you don't care about order, there's another way:

_.toPairs(obj).filter(([k, v]) => _.include(keys, k)).map(x => _.fromPairs([x]))
Adam R. Nelson
  • 541
  • 4
  • 11
  • Strange, I tested it (at least the first one) on JSFiddle and it worked... what version of LoDash are you using? If you're using an old version (like the 2.x on JSFiddle), you need to replace `fromPairs` with `zipObject`. – Adam R. Nelson Sep 05 '17 at 13:16
0

A one-liner lodash solution would be to use lodash#toPairs to convert the object into an array of key-value pairs, lodash#chunk to wrap each pairs with another array as preparation for mapping each item to form the pairs into an object using lodash#map with a lodash#fromPairs iteratee.

var result = _(data).toPairs().chunk().map(_.fromPairs).value();

var data = {
  tom: 11,
  jim: 22,
  jay: 13
};

var result = _(data).toPairs().chunk().map(_.fromPairs).value();
  
console.log(result);
.as-console-wrapper{min-height:100%;top:0}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

An Vanilla JS ES6 solution would be to use Object#keys to get an array of keys from the object, Array#map to map each keys to associate each key to form an array of objects. We used the ES6 computed property names feature to associate the keys directly into an anonymous object.

var result = Object.keys(data).map(key => ({ [key]: data[key] }));

var data = {
  tom: 11,
  jim: 22,
  jay: 13
};

var result = Object.keys(data).map(key => ({ [key]: data[key] }));
  
console.log(result);
.as-console-wrapper{min-height:100%;top:0}

If the browsers that you use doesn't support ES6 then you can simply convert the solution above into this:

var result = Object.keys(data).map(function(key) {
  var object = {};
  object[key] = data[key];
  return object;
});

var data = {
  tom: 11,
  jim: 22,
  jay: 13
};

var result = Object.keys(data).map(function(key) {
  var object = {};
  object[key] = data[key];
  return object;
});
  
console.log(result);
.as-console-wrapper{min-height:100%;top:0}
ryeballar
  • 29,658
  • 10
  • 65
  • 74
0

Basically for a one liner solution to this you don't need lodash, just simple filter and map would be enough, however if you want you can use lodash.

//this is your source object 
var keys = {
  tom: 11,
  jim: 22,
  jay: 13
}

Now, Lets assume you have 2 (some) arrays

var input1 = ['jim', 'tom', 'kim', 'jay'];
var input2 = ['may', 'jay', 'tom', 'jim'];

And here we go:

//for first input
input1.filter(s=>keys[s]).map(s=> ({[s]: keys[s]}));
//for secondinput
input2.filter(s=>keys[s]).map(s=> ({[s]: keys[s]}));

Here is a working snippet for you:

var keys = {
  tom: 11,
  jim: 22,
  jay: 13
}

var input1 = ['jim', 'tom', 'kim', 'jay'];
var input2 = ['may', 'jay', 'tom', 'jim'];

var output1 = input1.filter(s=>keys[s]).map(s=> ({[s]: keys[s]}));
var output2 = input2.filter(s=>keys [s]).map(s=> ({[s]: keys[s]}));

console.log("Output1: ", JSON.stringify(output1));
console.log("Output2: ", JSON.stringify(output2));
Koushik Chatterjee
  • 4,106
  • 3
  • 18
  • 32