ajbee
ajbee

Reputation: 3641

How to change all occurrences of an object key in an array of objects

I have this sample data:

const data = [
  {
    id: 1,
    title: 'Sports',
    menus: [
      {
        id: 2,
        title: 'Basketball',
        menus: [
          {
            id: 3,
            title: 'NBA',
          },
          {
            id: 4,
            title: 'NCAA',
          },
          {
            id: 5,
            title: 'G-League',
          },
        ],
      },
    ],
  },
  {
    id: 100,
    title: 'Names',
    menus: [],
  },
];

I want to change all the menus keys into children, so the result would be:

const result = [
  {
    id: 1,
    title: 'Sports',
    children: [
      {
        id: 2,
        title: 'Basketball',
        children: [
          {
            id: 3,
            title: 'NBA',
          },
          {
            id: 4,
            title: 'NCAA',
          },
          {
            id: 5,
            title: 'G-League',
          },
        ],
      },
    ],
  },
  {
    id: 100,
    title: 'Names',
    children: [],
  },
];

I'm trying with this code:

const replacer = { menus: 'children' };
const transform = useCallback(
    (obj) => {
      if (obj && Object.getPrototypeOf(obj) === Object.prototype) {
        return Object.fromEntries(Object.entries(obj).map(([k, v]) => [replacer[k] || k, transform(v)]));
      }
      return obj;
    },
    [replacer]
  );

but it only changes the keys at the first level. How can I make it work?

Upvotes: 0

Views: 241

Answers (3)

trincot
trincot

Reputation: 350079

You can use a recursive function that makes use of destructuring:

const  replaceKey = arr => 
    arr.map(({menus, ...o}) => 
        menus ? {...o, children: replaceKey(menus)} : o);

const data = [{id: 1,title: 'Sports',menus: [{id: 2,title: 'Basketball',menus: [{id: 3,title: 'NBA',},{id: 4,title: 'NCAA',},{id: 5,title: 'G-League',},],},],},{id: 100,title: 'Names',menus: [],},];

console.log(replaceKey(data));

To provide the old/new key dynamically, use the following variant:

const  replaceKey = (arr, source, target) =>
    arr.map(({[source]: v, ...o}) =>
        v ? {...o, [target]: replaceKey(v, source, target)} : o);

const data = [{id: 1,title: 'Sports',menus: [{id: 2,title: 'Basketball',menus: [{id: 3,title: 'NBA',},{id: 4,title: 'NCAA',},{id: 5,title: 'G-League',},],},],},{id: 100,title: 'Names',menus: [],},];

console.log(replaceKey(data, "menus", "children"));

This code assumes that values for the given key are arrays. If for some reason their values could be something else, then the code needs a bit more extension:

const data = [{id: 1,title: 'Sports',menus: [{id: 2,title: 'Basketball',menus: [{id: 3,title: 'NBA',},{id: 4,title: 'NCAA',},{id: 5,title: 'G-League',},],},],},{id: 100,title: 'Names',menus: 13,},];

const  replaceKey = (arr, source, target) =>
    Array.isArray(arr) ? arr.map(({[source]: value, ...o}) =>
        value !== undefined ? {...o, [target]: replaceKey(value, source, target)} : o
    ) : arr;

console.log(replaceKey(data, "menus", "children"));

To see the effect of this code, the value for the very last menus key was changed to 13.

Upvotes: 4

Muhammed Moussa
Muhammed Moussa

Reputation: 5195

check this package: paix:
that's take original source object and desired keys replacement then return a new object with desired keys, ex:

npm i paix

import { paix } from 'paix';

const data = [
  {
    id: 1,
    title: 'Sports',
    menus: [
      {
        id: 2,
        title: 'Basketball',
        menus: [
          {
            id: 3,
            title: 'NBA',
          },
        ],
      },
    ],
  },
  {
    id: 100,
    title: 'Names',
    menus: [],
  },
];
                   
const keys_swap = {menus: "children"};
const result = data.map(i => paix(i, keys_swap));

Upvotes: 0

mplungjan
mplungjan

Reputation: 177692

If the object is not big:

let data=[{id:1,title:'Sports',menus:[{id:2,title:'Basketball',menus:[{id:3,title:'NBA',},{id:4,title:'NCAA',},{id:5,title:'G-League',},],},],},{id:100,title:'Names',menus:[],},];

data = JSON.parse(JSON.stringify(data).replace(/"menus"\:/g,'"children":'))
console.log(data)

Upvotes: 0

Related Questions