[英]Find object by properties from array
With an array, a value, and and an object with nested objects: 有一个数组,一个值和一个带有嵌套对象的对象:
Object 宾语
mesh
Array 数组
['options', 'range', 'x']
Value 值
12.5
Is it possible to translate this to update a property, eg 是否可以翻译此属性以更新属性,例如
mesh.options.range.x = 12.5
Attempted: 尝试:
index = (obj, i) ->
obj[i]
arr.reduce(index, obj) = 12.5
Update 更新资料
Thank you all for the elegant solutions. 谢谢大家的优雅解决方案。
Using .reduce()
is actually pretty nice for this: 实际上,使用.reduce()
很不错:
// current object----| |----current key
// v v
arr.reduce(function(obj, key) {
return obj == null ? obj : obj[key];
}, window.mesh);
// ^
// |-- initial object
Your attempt to use .reduce()
needed to pass a function that manages the "accumulation". 您尝试使用.reduce()
需要传递一个用于管理“累加”的函数。
Here, as long as the previous obj
wasn't null
or undefined
, it'll return the key
of the current obj
, which becomes the next obj
. 在这里,只要前一个obj
不为null
或undefined
,它将返回当前obj
的key
,该key
成为下一个obj
。
Then since you need to assign a value, you'd actually want to get the value of the second to last key. 然后,由于您需要分配一个值,因此您实际上要获取倒数第二个键的值。
var o = arr.slice(0,-1).reduce(function(obj, key) {
return obj == null ? obj : obj[key];
}, window.mesh);
And then check its existence and use the last item in arr
to do the assignment. 然后检查其存在并使用arr
的最后一项进行分配。
o && o[arr.pop()] = 12.5;
All of this can be abstracted away into a function that does one or the other based on how many arguments were passed. 所有这些都可以抽象为一个函数,该函数根据传递的参数数量来执行一个或另一个函数。
function setFromArray(obj, arr, val) {
var keys = arguments.length < 3 ? arr.slice() : arr.slice(0, -1);
var o = keys.slice(0,-1).reduce(function(obj, key) {
return obj == null ? obj : obj[key];
}, window.mesh);
if (arguments.length < 3)
return o;
else
o && o[keys.pop()];
}
Here's a general solution: 这是一个常规解决方案:
function setPropertyPath(obj, path, value) {
var o = obj;
for (var i = 0; i < path.length - 1; i++) {
o = o[path[i]];
}
o[path[path.length - 1]] = value;
}
Usage: 用法:
var obj = { a: { b: { c: 0 } } };
setPropertyPath(obj, ['a', 'b', 'c'], 10);
console.log(obj.a.b.c); // prints '10'
var mesh = {},
arr = ['options','range','x'],
value = 12.5;
mesh[arr[0]][arr[1]][arr[2]] = value;
If array length is static do something like this: 如果数组长度是静态的,请执行以下操作:
mesh[array[0]][array[1]][array[2]] = value;
However, one problem with this is that javascript doesn't do autovivification, so if you're accessing a key value that isn't previously defined you could run into errors (if mesh.options hasn't been defined then the above will throw an error because you can't assign to it). 但是,与此相关的一个问题是javascript无法自动进行生存,因此,如果您访问的是先前未定义的键值,则可能会遇到错误(如果未定义mesh.options,则以上内容将抛出错误错误,因为您无法分配给它。 To solve that you might abstract this out into a function that handles things recursively: 为了解决这个问题,您可以将其抽象为一个递归处理函数的函数:
http://jsfiddle.net/h4jVg/ http://jsfiddle.net/h4jVg/
function update_val(obj, array, val, prev) {
if (array.length == 0) {
obj = val;
return;
}
var cur = array.shift();
if(array.length == 0) {
obj[cur] = val;
return;
} else if (obj[cur] == undefined) {
obj[cur] = {};
}
update_val(obj[cur], array, val);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.