我有一组具有不同属性的对象:
var arr = [];
var obj_1 = {
'key_a': 'value_a',
'key_b': 'value_b'
};
arr.push(obj_1);
var obj_2 = {
'key_a': 'value_a',
'key_b': 'value_b',
'key_c': 'value_c'
};
arr.push(obj_2);
如果数组中的每个对象都不存在,我如何自动将新密钥(key_c)或任何其他密钥添加到数组中的每个对象?
所以数组看起来像这样:
[
{
'key_a': 'value_a'
'key_b': 'value_b'
'key_c': ''
},
{
'key_a': 'value_a'
'key_b': 'value_b'
'key_c': 'value_c'
}
]
请注意:我正在构建一个Web scraper,未知的键/属性将添加到对象中,并在foreach循环中推送到数组。
答案 0 :(得分:5)
如果新密钥(key_c)或任何其他密钥不存在,我如何自动将新密钥(key_c)或任何其他密钥添加到数组中的每个对象并使用空值?
你必须旋转数组,检查每个对象是否还有他们没有的密钥,并添加它们,这将是一种痛苦。
相反,您可以拥有一个原型对象,其中包含所有具有默认值的属性,并在所有具体对象后面使用该原型。当您了解新密钥时,使用默认值将它们添加到原型中,并且它们似乎可以追溯地在所有先前对象上神奇地出现(因为您正在修改它们背后的原型)。稍后从对象获取属性时,他们将使用自己的值来获取他们拥有的属性,并使用原型中的默认值来表示他们不具备的属性。
要使用其他对象作为原型创建对象,请使用while (<$fh>)
{
my @data = split /,/, $_, 5;
}
:
Object.create
如果你正在接收你需要从其他地方跟踪的对象(例如,你没有创建它们),你可以使用一个函数来创建一个对象,使用&#34;默认值&#34 ;然后复制您收到的对象的任何属性。这也是一个标记您尚未了解的新属性并为其设置默认值的机会:
obj = Object.create(defaults); // defaults is the prototype object to use
直播示例:
var defaults = {};
var list = [];
function addToList(obj) {
// Create our entry backed by the defaults
var entry = Object.create(defaults);
// Loop through the new object's keys...
Object.keys(obj).forEach(function(key) {
// ...adding a default if it's a new key
if (!defaults.hasOwnProperty(key)) {
defaults[key] = /*...default value...*/;
}
// ...and grabbing the value
entry[key] = obj[key];
});
// Put it on the list
list.push(entry);
}
&#13;
var defaults = {};
var list = [];
function addToList(obj) {
// Create our entry backed by the defaults
var entry = Object.create(defaults);
// Loop through the new object's keys...
Object.keys(obj).forEach(function(key) {
// ...adding a default if it's a new key
if (!defaults.hasOwnProperty(key)) {
defaults[key] = "default for " + key;
}
// ...and grabbing the value
entry[key] = obj[key];
});
// Put it on the list
list.push(entry);
}
addToList({a: "a0", b: "b0"}); // Has a and b
addToList({a: "a1", c: "c1"}); // Has a and c
addToList({b: "b2", d: "d2"}); // Has b and d
list.forEach(function(entry, index) {
snippet.log("Object #" + index + ":");
Object.keys(defaults).forEach(function(key) {
snippet.log(key + " = " + entry[key]);
});
});
&#13;
答案 1 :(得分:2)
通过扩展函数实现属性缺失的一种迂回方式,如下所示:
(function() {
'use strict';
var commonPrototype = new function() {
var self = this;
self.getProp = function(key) {
if (this.hasOwnProperty(key)) {
return this[key];
}
return 'DEFAULT'; //change to empty string if you want
}
};
var a = [];
var lit = {
'key1' : 'key1Value',
'key2' : 'key2Value'
};
extend(lit, commonPrototype);
a.push(lit);
var lit2 = {
'key1' : 'key1Value',
'key2' : 'key2Value',
'key3' : 'key3Value'
};
extend(lit2, commonPrototype);
a.push(lit2);
console.log(a[1].getProp('key3')); //return actual lit2 key3 value
console.log(a[0].getProp('key3')); //return the default (DEFAULT or whatever you want) when it's missing
function extend(o, p) {
o.getProp = p.getProp;
}
}());
这里唯一的问题是默认访问者无法正常工作,但您可以使用getProp(keyName)
获取值。
当使用Proxy
这样的ES6时,这可以更好:
function proxify(o) {
return new Proxy(o, {
get : function(target, name, receiver) {
return (target.hasOwnProperty(name)) ? target[name] : "DEFAULT";
}
});
}
var l1 = proxify({ key1: '1', key2: '2'});
var l2 = proxify({ key1: '1.1', key2: '1.2', key3: '1.3'});
console.log(`l1.key3: ${l1.key3}`);
console.log(`l2.key3: ${l2.key3}`);
我希望您可以用自己的代码替换prop访问器的方式,但这样做。
自2015-04-26起,该代码可在Firefox 37+和Microsoft Edge(以前的Spartan)上执行。
答案 2 :(得分:2)
我创建了一个特殊对象来充当容器。此特殊对象将存储推入其中的对象的键以及对象。
一旦用户想要从中检索对象,该对象将更新存储对象的键,以确保所有对象具有正确值的相同键。
{{1}}
您可以为此对象添加功能以改进它。
<强> Fiddle 强>
希望它有所帮助。
答案 3 :(得分:0)
不确定我是否完全理解您的问题,但如果您想要将对象添加到对象中,如果他们没有这样做,您可以这样做:
var obj_1 = {
'key_a': 'value_a',
'key_b': 'value_b'
};
if(!obj_1.hasOwnProperty("key_c"))
obj_1.key_c=undfined;
这个想法是你正在检查对象属性是否存在而不是未定义的值。
其他选项是致电Object.keys(obj_1)//["key_a","key_b"]
并检查所需的密钥是否在数组中。
答案 4 :(得分:0)
这是一个解决方案:
var keysSet = new Set();
var pushWithFill = function(arr, newObject) {
// add keys from the new obj to the dictionary
// and add missing properties to this object
keysSet.forEach(function(key){
if (!newObject.hasOwnProperty(key)) {
newObject[key] = '';
}
});
for (var property in newObject) {
keysSet.add(property);
}
// process all stored objects to add keys from the new one to them
arr.forEach(function(storedObj, index){
for (var property in newObject) {
if (!storedObj.hasOwnProperty(property)) {
storedObj[property] = '';
}
}
});
arr.push(newObject);
};
使用示例:
var arr = [];
var obj_1 = {
'key_a': 'value_a',
'key_b': 'value_b'
};
var obj_2 = {
'key_a': 'value_a',
'key_b': 'value_b',
'key_c': 'value_c'
};
var obj_3 = {
'key_a': 'value_a'
}
pushWithFill(arr, obj_1);
pushWithFill(arr, obj_2);
pushWithFill(arr, obj_3);
结果:
[{
" key_a " : " value_a ",
" key_b " : " value_b ",
" key_c " : " "
}, {
" key_a " : " value_a ",
" key_b " : " value_b ",
" key_c " : " value_c "
}, {
" key_a " : " value_a ",
" key_b " : " ",
" key_c " : " "
}
]