-2

I want to rename keys in an object, that contains children objects that look the same.

This is my starting object:

objs = {
   "one":{
      "title":"bla",
      "amount":5,
      "children":[
         {
            "title":"bla",
            "identifier":"some text"
         },
         {
            "title":"bla2",
            "identifier":"some text2"
         }
      ]
   },
   "two":{
      "title":"bla",
      "amount":5,
      "children":[
         {
            "title":"bla",
            "identifier":"some text"
         },
         {
            "title":"bla2",
            "identifier":"some text2"
         }
      ]
   }
}

and I want it to transform it into this:

objs = {
   "one":{
      "text":"bla",
      "amount":5,
      "items":[
         {
            "text":"bla",
            "identifier":"some text"
         },
         {
            "text":"bla2",
            "identifier":"some text2"
         }
      ]
   },
   "two":{
      "text":"bla",
      "amount":5,
      "items":[
         {
            "text":"bla",
            "identifier":"some text"
         },
         {
            "text":"bla2",
            "identifier":"some text2"
         }
      ]
   }
}

So basically I want to rename every key children to items and every key title to text, no matter how deep the object children go. I already tried using spread & Destructuring Assignment in foreach loops but it did not work very well..

Tom Marienfeld
  • 716
  • 3
  • 14
  • Please visit the [help], take the [tour] to see what and [ask]. Do some research, search for related topics on SO; if you get stuck, post a [mcve] of your attempt, noting input and expected output using the `[<>]` snippet editor. – mplungjan May 07 '20 at 14:34

4 Answers4

1

Maybe like this:

var objs = {
   "one":{
      "title":"bla",
      "amount":5,
      "children":[
         {
            "title":"bla",
            "identifier":"some text"
         },
         {
            "title":"bla2",
            "identifier":"some text2"
         }
      ]
   },
   "two":{
      "title":"bla",
      "amount":5,
      "children":[
         {
            "title":"bla",
            "identifier":"some text"
         },
         {
            "title":"bla2",
            "identifier":"some text2"
         }
      ]
   }
};



function transorm_obj(_obj){
 var out = [];
 for(var key in _obj){
  var new_obj = {};
  for(var prop in _obj[key]){
    if(prop == 'children'){
            new_obj['items'] = transorm_obj(_obj[key][prop]);
    }else if(prop == 'title'){
             new_obj['text'] = _obj[key][prop];
    }else{
     new_obj[prop] = _obj[key][prop];
    }

        }
        out.push(new_obj);
 }
 return out;
}

console.log(transorm_obj(objs));
mscdeveloper
  • 2,749
  • 1
  • 10
  • 17
0

So you want to rename children to items? Here's one option using a for in loop to "rename" your property.

const objs = {
   "one":{
      "title":"bla",
      "amount":5,
      "children":[
         {
            "title":"bla",
            "identifier":"some text"
         },
         {
            "title":"bla2",
            "identifier":"some text2"
         }
      ]
   },
   "two":{
      "title":"bla",
      "amount":5,
      "children":[
         {
            "title":"bla",
            "identifier":"some text"
         },
         {
            "title":"bla2",
            "identifier":"some text2"
         }
      ]
   }
};


for (const obj in objs) {
  objs[obj].items = objs[obj].children;
  delete objs[obj].items;
}

console.log(objs);

Or

const objs = {
   "one":{
      "title":"bla",
      "amount":5,
      "children":[
         {
            "title":"bla",
            "identifier":"some text"
         },
         {
            "title":"bla2",
            "identifier":"some text2"
         }
      ]
   },
   "two":{
      "title":"bla",
      "amount":5,
      "children":[
         {
            "title":"bla",
            "identifier":"some text"
         },
         {
            "title":"bla2",
            "identifier":"some text2"
         }
      ]
   }
};

const newObjs = Object.keys(objs).reduce( (acc, curr) => {
  const updatedObj = { ...objs[curr], items: objs[curr].children };
  delete updatedObj.children
  acc[curr] = { ...updatedObj };
  return acc;
}, {});

console.log(newObjs)
mwilson
  • 12,295
  • 7
  • 55
  • 95
0

It is not possible to rename, but you can re-assign the value as follow:

Object.keys(objs)
    .filter(key => objs[key].children)
    .forEach(key => { 
        objs[key].items = objs[key].children; 
        delete objs[key].children; 
    });
GabrielBiga
  • 388
  • 5
  • 19
0

Here is a generic recursive map function I wrote in a recent answer -

const map = (fk = identity, fv = identity, x = null) =>
  Array.isArray(x)
    ? x.map(v => map(fk, fv, v))
: Object(x) === x
    ? Object.fromEntries(
        Object.entries(x).map(([ k, v ]) =>
          [ fk(k)
          , map(fk, fv, v)
          ] 
        )
      )
: fv(x)

Higher-order functions are particularly helpful because they can be used in many practical ways -

const keyReplacer = (k = "") =>
{ if (k === "title") return "text"
  if (k === "children") return "items"
  else return k
}

const objs = // <-- don't forget const keyword
  { ... }

const result =
  map(keyReplacer, identity, objs)

// => ... 

Run the snippet below to see the output -

const identity = x =>
  x
  
const map = (fk = identity, fv = identity, x = null) =>
  Array.isArray(x)
    ? x.map(v => map(fk, fv, v))
: Object(x) === x
    ? Object.fromEntries(
        Object.entries(x).map(([ k, v ]) =>
          [ fk(k)
          , map(fk, fv, v)
          ] 
        )
      )
: fv(x)

const objs = // <-- don't forget const keyword
  {one:{title:"bla",amount:5,children:[{title:"bla",identifier:"some text"},{title:"bla2",identifier:"some text2"}]},two:{title:"bla",amount:5,children:[{title:"bla",identifier:"some text"},{title:"bla2",identifier:"some text2"}]}}

const keyReplacer = (k = "") =>
{ if (k === "title") return "text"
  if (k === "children") return "items"
  else return k
}

const result =
  map(keyReplacer, identity, objs)

console.log(result)

An obvious improvement to this would replace the linear if stack with a logarithmic dictionary look-up -

const keyReplacer = (dict = {}) => (k = "") =>
{ const r = dict[k]
  return r === undefined ? k : r
}

const replacements = 
  { title: "text", children: "items" }

const result =
  map(keyReplacer(replacements), identity, objs)
Mulan
  • 129,518
  • 31
  • 228
  • 259