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

Time:02-15

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"
    }
]

CodePudding user response:

There is a way to do it without map :

var result = [];
Object.keys(options).forEach((element) => {
  result.push({ id: element, ...options[element] });
});

Output:

[
    {
        "id": "694",
        "title_694": "Tiger",
        "category_694": "848",
        "description_694": "long description"
    },
    {
        "id": "695",
        "title_694": "Turtles",
        "category_694": "347",
        "description_694": "long description"
    }
]

Ask me if you have more questions. But you need more code to remove id from new keys object

CodePudding user response:

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 }]
});

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"
    }
]

CodePudding user response:

Personally like you, I prefer not to manually build a whole new array.

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

let mutated = Object.values(Object.entries(options).map(([id, option]) => {
    return Object.assign({
        id: id,
    }, Object.fromEntries(Object.entries(option).map(([key, value]) => {
        return [key.replace(/_*\d $/g, ''), value];
    })));
}));

This lets the first map function create a new array accordingly, Object.assign ensures you have a single object from each, and the Object.entries and Object.fromEntries to convert to an array of pairs to then convert the keys, and then back from the array of pairs.

Have a read of the MDN documentation relating to Object.entries: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries

That links to the Object.fromEntries documentation, too.

As a side note, I've modified your regular expression to include the end-of-line match so it will modify something like w3tag_694 in the expected way. I would also suggest looking at changing the * in the regex to a to be a little stricter.

There is a caveat: fromEntries is a relatively new feature, but is supported by all major browsers still supported by their makers. Check the support: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries#browser_compatibility

  • Related