我正在尝试创建一个像
这样的javascript对象var allUserExpiry={};
allUserExpiry[aData.userId][aData.courseId][aData.uscId] = aData;
但我收到的错误如allUserExpiry[aData.userId]
未定义。
有没有办法,我可以设置多级JS-Object键?或者重要的是我应该allUserExpiry[aData.userId]={}
,然后allUserExpiry[aData.userId][aData.courseId]={}
?
如果有相同的实用功能,请告诉我。
答案 0 :(得分:7)
不,没有办法设置“多级键”。在尝试向其添加属性之前,需要初始化每个对象。
var allUserExpiry = {};
allUserExpiry[aData.userId] = {}
allUserExpiry[aData.userId][aData.courseId] = {}
allUserExpiry[aData.userId][aData.courseId][aData.uscId] = aData;
答案 1 :(得分:3)
或者你可以这样做:
function setByPath(obj, path, value) {
var parts = path.split('.');
var o = obj;
if (parts.length > 1) {
for (var i = 0; i < parts.length - 1; i++) {
if (!o[parts[i]])
o[parts[i]] = {};
o = o[parts[i]];
}
}
o[parts[parts.length - 1]] = value;
}
并使用:
setByPath(obj, 'path.path2.path', someValue);
这种方法有很多不足之处,但为了好玩......:)
答案 2 :(得分:2)
为什么不这样做?
var allUserExpiry={};
allUserExpiry[aData.userId] = {aData.courseId: {aData.uscId: aData}};
答案 3 :(得分:2)
使用ES6中的Computed属性名称,可以执行以下操作:
var allUserExpiry = {
[aData.userId] = {
[aData.courseId]: {
[aData.uscId]: aData
}
}
};
答案 4 :(得分:2)
我在IE9 +以及真正的浏览器中做了一个非常简单但很简单的方法。
鉴于var path = 'aaa.bbb.ccc.ddd.eee';
其中path
是您打算在对象中创建的内容,var result = {};
将创建对象{aaa: {bbb: {ccc: {ddd: {eee: {}}}}}
result = {}
path.split('.').reduce(function(prev, e) {
var newObj = {};
prev[e] = newObj;
return newObj;
}, result);
会将对象存储在result
。
split('.')
将输入转换为['aaa', 'bbb', 'ccc', 'ddd', 'eee']
reduce(function (...) {...}, result)
遍历split
创建的数组,并且每个条目都会将返回的值传递给下一个。在我们的例子中,我们在将新对象添加到旧对象之后传递新对象。这会创建一个对象链。 reduce
会返回您在其中返回的最后一个对象,因此我们必须事先定义result
。这依赖于使用引用,因此如果您期望您的代码由其他任何人维护,并且可能应该避免诚实,那么它将不会立即清楚它是如何工作的,但它至少可以工作。
答案 5 :(得分:1)
您还可以使用以下内容创建初始结构:
var x = function(obj, keys) {
if (!obj) return;
var i, t;
for (i = 0; i < keys.length; i++) {
if (!t) {
t = obj[keys[i]] = {};
} else {
t[keys[i]] = {};
t = t[keys[i]];
}
}
};
var a = {};
x(a, ['A', 'B', 'C', 'D', 'E', 'F']);
答案 6 :(得分:1)
另一种没有字符串或数组作为参数的方法。
function fillObject() {
var o = arguments[0];
for(var i = 1; i < arguments.length-1; i++) {
if(!o.hasOwnProperty(arguments[i])) {
o[arguments[i]] = {};
}
if(i < arguments.length-2) {
o = o[arguments[i]];
}else {
o[arguments[i]] = arguments[i+1]
}
}
}
var myObj = {"foo":{}};
fillObject(myObj,"back","to","the","future",2);
console.log(JSON.stringify(myObj));
// {"foo":{},"back":{"to":{"the":{"future":2}}}}
但我不会用它:-)这只是为了好玩。 因为我不喜欢太多的智能算法。 (如果属于这一类)
答案 7 :(得分:1)
使用lodash,您可以轻松地执行此操作(节点存在并对该节点进行空检查) ..
var lodash = require('lodash-contrib');
function invalidateRequest(obj, param) {
var valid = true;
param.forEach(function(val) {
if(!lodash.hasPath(obj, val)) {
valid = false;
} else {
if(lodash.getPath(obj, val) == null || lodash.getPath(obj, val) == undefined || lodash.getPath(obj, val) == '') {
valid = false;
}
}
});
return valid;
}
用法:
leaveDetails = {
"startDay": 1414998000000,
"endDay": 1415084400000,
"test": { "test1" : 1234 }
};
var validate;
validate = invalidateRequest(leaveDetails, ['startDay', 'endDay', 'test.test1']);
它将返回布尔值。
答案 8 :(得分:1)
只需使用loadash,
ggplot(mat_long, aes(x = col, y = row, fill = as.character(value))) +
geom_tile(color = "black") +
scale_fill_manual(values = colors) +
theme_void()
答案 9 :(得分:1)
使用 reduce 功能的另一种解决方案(感谢Brian K)。
在这里,我们创建了针对一般提议的获取/设置。第一个函数返回任意级别的值。考虑分隔符来分割密钥。该函数返回从键的数组中的最后一个索引引用的值
第二个函数将考虑拆分键的最后一个索引来设置新值
代码:
function getObjectMultiLevelValue(_array,key,separator){
key = key.split(separator || '.');
var _value = JSON.parse(JSON.stringify(_array));
for(var ki in key){
_value = _value[key[ki]];
}
return _value;
}
function setObjectMultiLevelValue(_array,key,value,forcemode,separator){
key.split(separator || '.').reduce(function(prev, currKey, currIndex,keysArr) {
var newObj = {};
if(prev[currKey] && !forcemode){
newObj = prev[currKey];
}
if(keysArr[keysArr.length-1] == currKey){
newObj = value;
prev[currKey] = newObj;
}
prev[currKey] = newObj;
return newObj;
}, _array);
return _array;
}
//testing the function
//creating an array
var _someArray = {a:'a',b:'b',c:{c1:'c1',c2:{c21:'nothing here...'}}};
//a multilevel key to test
var _key = 'a,a1,a21';
//any value
var _value = 'new foo in a21 key forcing replace old path';
//here the new value will be inserted even if the path exists (forcemode=true). Using comma separator
setObjectMultiLevelValue(_someArray,_key,_value,true,',');
console.log('_someArray:');
console.log(JSON.stringify(_someArray));
//inserting another value in another key... using default separator
_key = 'c.c2.c21';
_value = 'new foo in c21 key';
setObjectMultiLevelValue(_someArray,_key,_value);
console.log('_someArray:');
console.log(JSON.stringify(_someArray));
//recovering the saved value with different separators
_key = 'a,a1,a21';
console.log(getObjectMultiLevelValue(_someArray,_key,','));
_key = 'c.c2.c21';
console.log(getObjectMultiLevelValue(_someArray,_key));