在对象数组中填写缺少的属性

时间:2016-11-03 20:42:46

标签: javascript arrays json

在对象数组中填充缺失属性的最佳方法是什么,例如:

[
    {
        name: 'Tom',
        number: '01234 567 890',
        website: 'http://www.tom.com'
    },
    {
        name: 'Richard',
        number '07777 666 555'
    },
    {
        name: 'Harry',
        website: 'http://www.harry.com'
    }
]

我需要使用空值添加缺少的属性,这样当我传递此数组以在HTML表格或CSV文件等内容中呈现时,所有内容都会正确排列。我想要两次传递数组,一次获取所有可能的属性,第二次将具有空值的缺少属性添加到它不存在的每个对象。有更好的方法吗?

编辑:在我获得数据之前,我不知道密钥是什么,它来自API并且并不总是明确请求密钥。

我的最终解决方案

谢谢大家,似乎两通方法确实是最好的方法。在我开始使用提供的示例开始编写之后,我意识到属性的顺序没有得到维护。这就是我如何填写缺少的道具,并保持正确的顺序。欢迎任何有关潜在改进的建议。



var fillMissingProps = function(arr) {
    // build a list of keys in the correct order
    var keys = [];
    arr.forEach(function(obj) {
        var lastIndex = -1;
        Object.keys(obj).forEach(function(key, i) {
            if (keys.includes(key)) {
                // record the position of the existing key
                lastIndex = keys.lastIndexOf(key);
                if (lastIndex < i) {
                    // this key is in the wrong position so move it
                    keys.splice(i, 0, keys.splice(lastIndex, 1)[0]);
                    lastIndex = i;
                }
            } else {
                // add the new key in the correct position
                // after the previous existing key
                lastIndex++;
                keys.splice(lastIndex, 0, key);
            }
        });
    });

    // build a template object with all props set to null
    // and in the correct position
    var defaults = {};
    keys.forEach(function(key) {
        defaults[key] = null;
    });

    // and update the array by overwriting each element with a
    // new object that's built from the template and the original object
    arr.forEach(function(obj, i, arr) {
        arr[i] = Object.assign({}, defaults, obj);
    });

    return arr;
};

/** TEST **/

var currentArray = [
    {
        website: 'http://www.unknown.com'
    },
    {
        name: 'Tom',
        number: '01234 567 890',
        website: 'http://www.tom.com'
    },
    {
        title: 'Mr',
        name: 'Richard',
        gender: 'Male',
        number: '04321 666 555'
    },
    {
        id: '003ABCDEFGHIJKL',
        name: 'Harry',
        website: 'http://www.harry.com',
        mobile: '07890 123 456',
        city: 'Brentwood',
        county: 'Essex'
    }
];

var newArray = fillMissingProps(currentArray);

for (var i = 0; i < newArray.length; i++) {
    for (var prop in newArray[i]) {
        console.log(prop + ": " + newArray[i][prop]);
    }
    console.log('---------');
}
&#13;
&#13;
&#13;

5 个答案:

答案 0 :(得分:4)

鉴于您并不知道应该存在哪些密钥,您别无选择,只能对数组进行两次迭代:

// build a map of unique keys (with null values)
var keys = {}
array.forEach(el => Object.keys(el).forEach(k => keys[k] = null));

// and update the array by overwriting each element with a
// new object that's built from the null map and the original object
array.forEach((el, ix, a) => a[ix] = Object.assign({}, keys, el));

答案 1 :(得分:0)

使用Array.prototype.map()

const arr = [
  {
    name: 'Tom',
    number: '01234 567 890',
    website: 'http://www.tom.com',
  },
  {
    name: 'Richard',
    number: '07777 666 555',
  },
  {
    name: 'Harry',
    website: 'http://www.harry.com',
  },
];
const newArr = arr.map(x => (
  arr.map(x => Object.keys(x))
    .reduce((a, b) =>
      (b.forEach(z => a.includes(z) || a.push(z)), a)
    )
  .forEach(
    y => (x[y] = x.hasOwnProperty(y) ? x[y] : null)
  ), x)
);
console.log(newArr);

答案 2 :(得分:0)

您可以使用for..of循环获取所有密钥并设置所有密钥,.map()以迭代所有Object.keys(),重新定义原始数组

&#13;
&#13;
var arr = [{
  name: 'Harry',
  website: 'http://www.harry.com'
},{
  name: 'Tom',
  number: '01234 567 890',
  website: 'http://www.tom.com'
}, {
  name: 'Richard',
  number: '07777 666 555'
}];

for (var obj of arr) {
  for (var key of Object.keys(obj)) {
    arr = arr.map(o => (o[key] = o[key] || null, o))
  }
};

console.log(arr);
&#13;
&#13;
&#13;

答案 3 :(得分:0)

这是一个更有趣的答案,它有点有趣,但它会在新属性出现时动态构建您的对象:

&#13;
&#13;
var currentArray = [
    {
        name: 'Tom',
        number: '01234 567 890',
        website: 'http://www.tom.com'
    },
    {
        name: 'Richard',
        number: '07777 666 555'
    },
    {
        name: 'Harry',
        website: 'http://www.harry.com'
    }
]

var newArray = []

function NewObject() {

}

for(var i = 0; i < currentArray.length; i++){
  
  var nObj = new NewObject();
  
  for(var prop in currentArray[i]){   
    if(!NewObject.hasOwnProperty(prop))
        NewObject.prototype[prop] = null;
    nObj[prop]=currentArray[i][prop];   
  }
  
  newArray.push(nObj);
}

for(var i = 0; i < newArray.length; i++){
     for(var prop in newArray[i]){ 
         console.log(prop+ ": "+newArray[i][prop]);
     }  
    console.log('---------');
}



  
&#13;
&#13;
&#13;

它会根据您提供的对象构建新对象,并在对象尚未存在的情况下为对象添加新属性。

这个想法更多的是出于好奇心,所以任何评论都会很有趣:)

答案 4 :(得分:-1)

这样的事情可行:

for (var i = 0; i < arrayLength; i++) {
   yourArray[i].name = yourArray[i].name || null;
   yourArray[i].number = yourArray[i].number || null;
   yourArray[i].website= yourArray[i].website|| null;
}