0

How to transform {2:'b',3:'c',1:'a'} into [{1:'a'},{2:'b'},{3:'c'}] by lodash?

David Henry
  • 101
  • 1
  • 7

4 Answers4

6

It's fairly trivial using Object.keys + Array.map, you really don't need lodash:

const obj = {2:'b',3:'c',1:'a'};
const arr = Object.keys(obj).map(key => ({ [key]: obj[key] }))

console.log(arr)

Regarding the lack of a sort function, the above code is exploiting the fact that numerically indexed Object keys are (per the spec) stored sequentially. Check the order for yourself:

console.log({2:'b',3:'c',1:'a'})

Here is the relevant portion of the spec

9.1.12 [[OwnPropertyKeys]] ( )

When the [[OwnPropertyKeys]] internal method of O is called the following steps are taken:

  1. Let keys be a new empty List.

  2. For each own property key P of O that is an integer index, in ascending numeric index order

    2a. Add P as the last element of keys.

Rob M.
  • 35,491
  • 6
  • 51
  • 50
  • I know object keys are not assumed to be sorted (https://stackoverflow.com/questions/29623333/sort-keys-in-javascript-object), but I didn't know Object.keys are typically sorted. Where can I find more info about this?? – kevguy Aug 21 '17 at 17:46
  • Updated my answer with a link to the spec and the relevant portion @kevlai22. Note that this only pertains to numerical indices – Rob M. Aug 21 '17 at 18:01
  • No problem @kevlai22, glad to help out! :) – Rob M. Aug 21 '17 at 18:13
2

With upcoming Javascript with Object.entries, you could map a new array with single objects.

var data = {2:'b',3:'c',1:'a'},
    result = Object
        .entries(data)
        .sort((a, b) => a[0] - b[0])
        .map(([k, v]) => ({ [k]: v }));

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

With lodash, you could use

var data = {2:'b',3:'c',1:'a'},
    result = _
        .chain(data)
        .toPairs(data)
        .sortBy([0])
        .map(o => _.fromPairs([o]));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

Lodash is not really necessary to accomplish what you want, but I'm still adding it anyway and add a sorted function. I've also included the native JavaScript way.

const obj = {b: 3, c: 2, a: 1};


const sortByKeys = object => {
  const keys = Object.keys(object)
  const sortedKeys = _.sortBy(keys)

  return _.map(sortedKeys, key => ({ [key]: object[key]}))
}

// the lodash way, and sorted
console.log(sortByKeys(obj))

// simpler way
const result = Object.keys(obj)
  .map(key => ({ [key]: obj[key] }))
  
 console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
kevguy
  • 4,328
  • 1
  • 24
  • 45
0

Why use lodash? Just use regular Javascript. Solution can be cleaned up a bit but the idea is to loop through your object and push your desired format into a new array. I also throw the sorting in there for convenience, but feel free to re-factor to your liking.

const obj = {2:'b',3:'c',1:'a'}

let newArr = [];
for (var key in obj) {
  newArr.push({[key]: obj[key]})
  newArr.sort((a, b) => a[key] > b[key])
}
console.log(newArr)
Christopher Messer
  • 2,040
  • 9
  • 13