Search code examples
javascriptsortingfilteringlodash

sort and filter an object array with lodash (or vanilla javascript)


I have this object I want to sort and filter by retaining only the 2 highest values by object.

obj={ A :[{
      asset: 9,
      biodiversity: 4,
      infrastructure: 15,
      deflation: 11,
      energy: 9
    }],
  B:[{
      asset: 12,
      biodiversity: 10,
      infrastructure: 9,
      deflation: 7,
      energy: 15
    }],
  C:[{
      asset: 2,
      biodiversity: 12,
      infrastructure: 6,
      deflation: 6,
      energy: 8
    }]}

I would like to sort the objects by their values and filter out the 2 highest e.g:

{A :[{
      infrastructure: 15,
      deflation: 11
    }],
  B:[{
      energy: 15,
      asset: 12
    }],
  C:[{
      biodiversity: 12,
      energy: 8
    }]}

I have tried this for sorting:

Object.keys(obj).forEach((a) => _.sortBy(obj[a][0])))

But that is wrong obviously. I am using lodash but will accept vanilla javascript solution as well.


Solution

  • You could get the entries of the inner objects and sort by value descending, get the top two key/value pairs and build a new object from it.

    const
        data = { A: [{ asset: 9, biodiversity: 4, infrastructure: 15, deflation: 11, energy: 9 }], B: [{ asset: 12, biodiversity: 10, infrastructure: 9, deflation: 7, nergy: 15 }], C: [{ asset: 2, biodiversity: 12, infrastructure: 6, deflation: 6, energy: 8 }]},
        result = Object.fromEntries(Object
            .entries(data)
            .map(([k, a]) => [k, a.map(o => Object.fromEntries(Object
                .entries(o)
                .sort((a, b) => b[1] - a[1])
                .slice(0, 2)
            ))])
        );
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }