设置javascript对象多级属性的简单方法
Easy way to set javascript object multilevel property?
我正在尝试创建一个类似的javascript对象
var allUserExpiry={};
allUserExpiry[aData.userId][aData.courseId][aData.uscId] = aData;
但我得到了一个类似allUserExpiry[aData.userId]
未定义的错误。
有没有办法,我可以设置多级JS对象键?或者我应该先做allUserExpiry[aData.userId]={}
,然后再做allUserExpiry[aData.userId][aData.courseId]={}
,这很重要吗?
请让我知道是否有任何实用功能可用于相同。
不,没有办法设置"多级键"。在尝试添加属性之前,您需要初始化每个对象。
var allUserExpiry = {};
allUserExpiry[aData.userId] = {}
allUserExpiry[aData.userId][aData.courseId] = {}
allUserExpiry[aData.userId][aData.courseId][aData.uscId] = aData;
使用ES6中的计算属性名称,可以执行以下操作:
var allUserExpiry = {
[aData.userId] = {
[aData.courseId]: {
[aData.uscId]: aData
}
}
};
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#Computed_property_names
只需使用loadash、
let object = {};
let property = "a.b.c";
let value = 1;
_.set(object, property, value); // sets property based on path
let value = _.get(object, property, default); // gets property based on path
或者你可以这样做:
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);
这种方法有很多弱点,但为了好玩…:)
为什么不直接这么做呢?
var allUserExpiry={};
allUserExpiry[aData.userId] = {aData.courseId: {aData.uscId: aData}};
我在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);
将该对象存储在CCD_ 8中。
工作原理:
split('.')
将输入转换为['aaa', 'bbb', 'ccc', 'ddd', 'eee']
reduce(function (...) {...}, result)
运行在split
创建的数组中,对于每个条目,都会将一个返回值传递给下一个条目。在我们的例子中,我们在将新对象添加到旧对象之后传递新对象。这将创建一个对象链。reduce
返回您在其中返回的最后一个对象,因此我们必须预先定义result
这依赖于使用引用,因此如果您希望您的代码由其他人维护,则不会立即清楚它是如何工作的,老实说,可能应该避免,但它至少可以工作。
您还可以使用以下方法创建初始结构:
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']);
另一种没有字符串或数组作为参数的方法。
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}}}}
但我不会用它:-)它只是为了好玩。因为我不喜欢太多的智能算法。(如果属于此类别)
使用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']);
它将返回布尔值。
另一个使用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));
假设我们的对象是
const data = {
//some other data
userInfo: {},
};
首先,定义对象的一个新属性
data.userInfo.vehicle = {};
然后简单地
data.userInfo.vehicle.vehicleType = state.userInfo.vehicleType;
- JQuery:向多个匹配结果添加换行符的最简单方法
- 访问对象的最简单方法'的单独财产
- 检查变量是否为字符串的简单方法
- 创建jQuery Slider的简单方法
- 你知道使用javascript游戏引擎的简单方法吗
- 解释分号的简单方法
- JavaScript:检查变量是否等于两个或多个值之一的简单方法
- 什么'这是使用jQuery将一些文本锚定到外部链接的最简单方法
- 实施会员系统的最简单方法是什么
- 每次使用 Javascript 加载页面时增加一个数字(变量)的简单方法
- .attr(“href”) 的问题!解决此问题的简单方法
- 出错时更改文本字段边框的最简单方法
- JavaScript:获取第一个月前 6 个月的日期的最简单方法
- 检查 redux 状态是否更改的简单方法
- 在CreateJS中加载视频的最简单方法
- 使用JavaScript过滤从网页复制的文本的最简单方法
- 创建在Javascript和PHP之间使用的唯一代码的最简单方法
- 什么's是处理多个js文件之间交互的简单方法,同时避免溢出全局变量
- 使用JS找出字符串中字符重复的最简单方法是什么
- 什么'这是一种基于if/if-else语句显示popover的简单方法