Search code examples
javascriptnode.jsfunctional-programmingmap-function

Return one object insted of array of objects using map function [codesandbox]


CodeSandbox example https://codesandbox.io/s/throbbing-worker-8s68n?file=/src/index.js

So I have an object and I'm updating the key name by removing the __number, I want to move the the 1st key [ 694 & 695 ] to inside the object as id = 694. I didn't manage to make that happen cause I get a new object for each key value ( see code below ).

var options = 
{
    "694": {
        "title_694": "Tiger",
        "category_694": "848",
        "description_694": "long description"
    },
    "695": {
        "title_694": "Turtles",
        "category_694": "347",
        "description_694": "long description"
    }
}

and here is my code

Object.keys(options).map( value => (
      {
        [value] : Object.keys(options[value]).map((keyName) => (
              {[keyName.replace(/_*\d+/g, '')] : options[value][keyName]}
            )) 
      }
  )
)

it output as below

[
    {
        "694": [
            {
                "title": "Tiger"
            },
            {
                "category": "848"
            },
            {
                "description": "long description"
            }
        ]
    },
    {
        "695": [
            {
                "title": "Turtles"
            },
            {
                "category": "347"
            },
            {
                "description": "long description"
            }
        ]
    }
]

How can make it work to output as below

[
    {
        "id": 694,
        "title": "Tiger",
        "category": "848",
        "description": "long description"
    },
    {
        "id":695,
        "title": "Turtles",
        "category": "347",
        "description": "long description"
    }
]

Solution

  • Using forEach without changing the key names in the original object

    var result = [];
    Object.keys(options).forEach((element) => {
    
      const item = Object.fromEntries(
        Object.entries(options[element]).map(([k, v]) => {
          k = k.replace(/_*\d+/g, "");
          return [k, v]
        })
      )
      result = [...result,{ id: element, ...item }]
      // Or you could use push which is slightly faster
      // To see benchmarks Google Spread operator vs push site: measurethat.net
      // result.push({ id: element, ...options[element] });
    });
    
    document.getElementById("app").innerHTML = `<pre>${JSON.stringify(
      result,
      null,
      4
    )}</pre>`;
    
    console.log(result);
    
    

    The output

    [
        {
            "id": "694",
            "title": "Tiger",
            "category": "848",
            "description": "long description"
        },
        {
            "id": "695",
            "title": "Turtles",
            "category": "347",
            "description": "long description"
        }
    ]