Search code examples
node.jsobjectlodashjavascript-objects

flatten nested object with topairs in lodash


I have an object like this:

let order={
  "john":{
    "hamburger":4
  },
  "alice":{
    "pizza":10,
    "milkshake":2
  },
  "bob":{
  }
}

that I would like to flatten like this:

let res=[
   ["john","hamburger",4],

   ["alice","pizza",4],
   ["alice","milkshake",4]

]

I know how to do it in reverse, using keyBy but how can I turn it from a recursive object to a recursive array? I tried using toPairs, but I can't figure out how to make it recursive


Solution

  • Use _.toPairs() to get an array of [name, items] pairs, which you iterate with _.flatMap(). Get the pairs from the items object, and use _.map() to create the arrays that include the info:

    const { flatMap, toPairs, map } = _
    
    const order = {"john":{"hamburger":4},"alice":{"pizza":10,"milkshake":2},"bob":{}}
    
    const result = flatMap(
      toPairs(order),
      ([name, items]) => 
        map(
          toPairs(items),
          ([product, price]) => [name, product, price]
        )
    )
    
    console.log(result)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

    In vanilla JS you can use Array.flatMap() with Object.entries() to get the same result:

    const order = {"john":{"hamburger":4},"alice":{"pizza":10,"milkshake":2},"bob":{}}
    
    const result = Object
      .entries(order)
      .flatMap(([name, items]) =>
        Object.entries(items)
          .map(([product, price]) => [name, product, price])
      )
    
    console.log(result)