重新创建对象数组的方法返回重复的相同对象的相同数组

时间:2017-02-07 19:26:02

标签: javascript arrays object

我正在开发一个函数,该函数将获取一组扁平嵌套对象并返回另一个数组,并重命名对象属性。

例如,此输入:

  

[

{
 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',
},
...... 
     

应该返回:

  

[

{
 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',
},
...... 
     

到目前为止的代码:

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

打印我创建的raw_object,每次迭代都会得到正确的对象。但是,最终变量仅由第一个对象组成,重复n次。

3 个答案:

答案 0 :(得分:3)

在循环的每次迭代中都需要一个新的raw_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
    .....

答案 1 :(得分:2)

我认为使用Array#mapArray#reduce方法可以更加简单。

// 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
  }, {});
})

&#13;
&#13;
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);
&#13;
&#13;
&#13; 实际问题在于您的代码是您在每次迭代中一次又一次地使用相同的对象,因此所有元素都引用单个对象。要解决此问题,您需要在循环内重新初始化新元素。

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

答案 2 :(得分:2)

您可以迭代数组并获取对象的键,拆分它们并获取新对象和值的最后一项。

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