2

I am working on a function that will take an array of flattened nested objects and return another array, with the object attributes renamed.

For example, this input:

[

{
 id: 13,
 student_name: 'John',
 parents.mother: 'Mia',
 parents.father: 'Milo',
 parents.mother.mother_education: 'msc',
 parents.father.father_education: 'bachelor',
},
{
 id: 13,
 student_name: 'Erica',
 parents.mother: 'Lea',
 parents.father: 'Theo',
 parents.mother.mother_education: 'bachelor',
 parents.father.father_education: 'high school',
},
...... 

]

should return:

[

{
 id: 13,
 student_name: 'John',
 mother: 'Mia',
 father: 'Milo',
 mother_education: 'msc',
 father_education: 'bachelor',
},
{
 id: 13,
 student_name: 'Erica',
 mother: 'Lea',
 father: 'Theo',
 mother_education: 'bachelor',
 father_education: 'high school',
},
...... 

]

The code so far:

function format_object(myobj){

    var raw_result = []; //the final variable - an array of objects
    var raw_obj = {}; //every object is kept here temporarly
    var depth = 0; //depth of the attribute name

    for(var i = 0; i< myobj.length; i++){ //for each object
        for(var attributename in myobj[i]){ //for each attribute
            depth = attributename.split(".").length-1; //calculate name depth
            if(depth == 0){ 
                raw_obj[attributename] = myobj[i][attributename]; //for simple attribute names, just copy them on the temp object
            }
            else{
                new_attribute = attributename.split('.')[depth] //for complex names, split last word
                raw_obj[new_attribute] = myobj[i][attributename];
            }
        }
        raw_result.push(raw_obj); //add the object we just created into the final variable
    }
    return raw_result;
}

Printing the raw_object I create, I get the correct object in each iteration. However , the final variable is composed of only the first object, repeated n times.

3 Answers 3

3

you need a new raw_object in each iteration of the loop, otherwise you are constantly changing properties of the same object.

When you push an object to the array it pushes a reference , not a copy .

So you are ending up with an array where each element is a reference to the exact same single object

var raw_result = []; //the final variable - an array of objects   
var depth = 0; //depth of the attribute name

for(var i = 0; i< myobj.length; i++){ //for each object

    var raw_obj = {}; // new object
    .....
Sign up to request clarification or add additional context in comments.

Comments

2

You could iterate the array and take the keys of the object, split them and take the last item for a new object and the value.

var data = [{ id: 13, 'student_name': 'John', 'parents.mother': 'Mia', 'parents.father': 'Milo', 'parents.mother.mother_education': 'msc', 'parents.father.father_education': 'bachelor', }, { id: 13, 'student_name': 'Erica', 'parents.mother': 'Lea', 'parents.father': 'Theo', 'parents.mother.mother_education': 'bachelor', 'parents.father.father_education': 'high school' }],
    newArray = data.map(function (o) {
        return Object.keys(o).reduce(function (r, k) {
            r[k.split('.').pop()] = o[k];
            return r;
        }, {});
    });
    
console.log(newArray);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

2

I think this can be much simpler using Array#map and Array#reduce methods.

// iterate over the object array
var res = data.map(function(obj) {
  // get all keys from object and iterate over the object 
  // to generate the updated object
  return Object.keys(obj).reduce(function(o, k) {
    // define the object property by splitting property name
    // and getting the last part
    o[k.split('.').pop()] = obj[k];
    // return the object reference
    return o;
    // define initial value as an empty object
  }, {});
})

var data = [

  {
    id: 13,
    student_name: 'John',
    'parents.mother': 'Mia',
    'parents.father': 'Milo',
    'parents.mother.mother_education': 'msc',
    'parents.father.father_education': 'bachelor',
  }, {
    id: 13,
    student_name: 'Erica',
    'parents.mother': 'Lea',
    'parents.father': 'Theo',
    'parents.mother.mother_education': 'bachelor',
    'parents.father.father_education': 'high school',
  }
]


var res = data.map(function(obj) {
  return Object.keys(obj).reduce(function(o, k) {
    o[k.split('.').pop()] = obj[k];
    return o;
  }, {});
})


console.log(res);

The actual problem lies in your code is that you are using the same object again and again in each iteration so all the elements refer to a single object. To resolve that you need to reinitialize within the loop for a new element.

for(var i = 0; i< myobj.length; i++){
   var raw_obj = {};
   // rest of your code

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.