Search code examples
javascriptlodash

transform the json array item to be flat in js


There is an json array from mongodb database as shown below.

[
    {
        "_id": {
            "fx_capacity_category": "100~300"
        },
        "fx_capacity": 314898.0758
    },
    {
        "_id": {
            "fx_capacity_category": "300~500"
        },
        "fx_capacity": 145033.1
    },
    ...
] 

This dataset needed to be transformed to be flat while removing the "_id"

[
    {
        "fx_capacity_category": "300~500"
        "fx_capacity": 145033.1
    },
    ...
]

I know the way of doing this by iterating the array item, and finding the item with '_id' and associated leaf key and transform. But that is not a smart way, wondering any better way, for example using lodash.


Solution

  • If you are interested in speed and have known props to extract, it's better to specify them explicitly, since the spread syntax is very slow. If you want to avoid field names, for .. in will be the fasted (like your first looping solution):

    const data = [{ _id: { fx_capacity_category: "100~300" }, fx_capacity: 314898.0758 }, { _id: { fx_capacity_category: "300~500" }, fx_capacity: 145033.1 }];
    
    const result = data.map(({fx_capacity, _id:{fx_capacity_category}})  => ({fx_capacity_category, fx_capacity})); 
    
    console.log(result);

    But what I usually do is to assign a class to data coming from the backend. See, you already have your data in your desired form except you need to move your _id props one level up, so:

    const data = [{ _id: { fx_capacity_category: "100~300" }, fx_capacity: 314898.0758 }, { _id: { fx_capacity_category: "300~500" }, fx_capacity: 145033.1 }];
    
    class FX{
      get fx_capacity_category(){
        return this._id.fx_capacity_category;
      }
    }
    
    data.forEach(item => Object.setPrototypeOf(item, FX.prototype));
    
    data.forEach(item => console.log(item.fx_capacity_category));

    And a benchmark.

    ` Chrome/123
    ---------------------------------------------------------------------------------------
    >                 n=2        |       n=20        |       n=200       |      n=2000     
    Alexander   ■ 1.00x x10m 182 | ■ 1.00x   x1m 192 | ■ 1.00x x100k 126 | ■ 1.00x x10k 148
    Nina          6.37x  x1m 116 |   4.90x x100k  94 |   7.86x  x10k  99 |   7.30x  x1k 108
    ---------------------------------------------------------------------------------------
    https://github.com/silentmantra/benchmark `
    

    const $chunk = [{ _id: { fx_capacity_category: "100~300" }, fx_capacity: 314898.0758 }, { _id: { fx_capacity_category: "300~500" }, fx_capacity: 145033.1 }];
    const $input = [];
    
    // @benchmark Nina
    $input.map(({ _id, ...rest }) => ({ ...rest, ..._id }));    
    
    // @benchmark Alexander
    $input.map(({fx_capacity, _id:{fx_capacity_category}})  => ({fx_capacity_category, fx_capacity})); 
    
    /*@skip*/ fetch('https://cdn.jsdelivr.net/gh/silentmantra/benchmark/loader.js').then(r => r.text().then(eval));