我正在尝试创建一个基于密钥对值进行求和的函数。这是一个示例对象:
{
"US": {
"q": 1,
"Atlanta": {
"q": 2
},
"Boston": {
"q": 1
}
}
我希望能够调用类似的函数:
var sum = plucky("q", obj);
// sum === 4;
我正在使用的功能,我相信我从过去某处的某个帖子中找到的几乎是正确的:
function pluckDeepKey(key, obj) {
if (_.has(obj, key)) {
return obj[key];
}
return _.reduce(_.flatten(_.map(obj, function(v) {
return _.isObject(v) ? pluckDeepKey(key, v) : [];
}), false), function(a,b) { return a + b });
}
但是,由于:return obj[key]
它找到第一个"q"
,返回该值并退出。我整天都在摸不着头脑,如果我把这个问题扔到SO那就认为对别人有帮助。
我认为SO和我未来的自我收集我在问题主体中探索的不同方法可能是有用的。
function plucky(key, obj) {
var sum = 0;
for (var prop in obj) {
if (_.has(obj, prop) && key === prop) {
sum += obj[prop];
}
else if (_.isObject(obj[prop])) {
sum += plucky(key, obj[prop]);
}
}
return sum;
}
function pluckDeepKey(key, obj) {
return _.reduce(obj, function(a, v) {
return a + (_.isObject(v) ? pluckDeepKey(key, v) : 0);
}, _.has(obj, key) ? obj[key] : 0);
}
function moriDeepKey(key, mmap) {
return m.reduce_kv(
function(a, k, v) { return a + (m.is_map(v) ? moriDeepKey(key, v) : 0); },
m.has_key(mmap, key) ? mmap.get(key) : 0,
mmap
);
}
function iDeepKey(key, imap) {
return imap.reduce(
function(a, v, k) { return a + (v instanceof I.Map ? iDeepKey(key, v) : 0); },
imap.has(key) ? imap.get(key) : 0,
imap
);
}
答案 0 :(得分:2)
我认为普通的javascript函数看起来更全面,更简单:
function plucky(key, obj) {
var sum = 0;
for (var prop in obj) {
if (obj.hasOwnProperty(prop) && key === prop) {
sum += obj[prop];
}
else if (Object.prototype.toString.call(obj[prop]) === '[object Object]') {
sum += plucky(key, obj[prop]);
}
}
return sum;
}
function plucky(key, obj) {
var sum = 0;
for (var prop in obj) {
if (obj.hasOwnProperty(prop) && key === prop) {
sum += obj[prop];
}
else if (Object.prototype.toString.call(obj[prop]) === '[object Object]') {
sum += plucky(key, obj[prop]);
}
}
return sum;
}
var obj = {
"US": {
"q": 1,
"Atlanta": {"q": 2},
"Boston": {"q": 1}
}
};
var sum = plucky("q", obj);
alert(sum);
答案 1 :(得分:2)
但是,由于:
return obj[key]
它找到第一个"q"
,返回该值并退出。
通过使用值作为累加器的开头,将两部分(obj.q
和递归调用)相加:
function pluckDeepKey(key, obj) {
return _.reduce(_.map(obj, function(v) {
return _.isObject(v) ? pluckDeepKey(key, v) : 0;
}), function(a,b) {
return a + b;
}, _.has(obj, key) ? obj[key] : 0);
}
我也删除了不必要的flatten
调用(pluckDeepKey
总是返回一个数字,空的arrray应该只是0
)。如果需要,您还可以将reduce
与map
加入
function pluckDeepKey(key, obj) {
return _.reduce(obj, function(a, v) {
return a + (_.isObject(v) ? pluckDeepKey(key, v) : 0);
}, _.has(obj, key) ? obj[key] : 0);
}
答案 2 :(得分:1)
除了另一个答案之外,您可以使用内置的所有内容以及使用递归功能实现更多功能:
var plucky = function(key, obj) {
return Object.keys(obj).reduce(function(acc, k) {
if ({}.toString.call(obj[k]) == '[object Object]') {
return acc + plucky(key, obj[k])
}
if (k === key) {
return acc + obj[k]
}
return acc
},0)
}
答案 3 :(得分:0)
您可以使用以下内容:
function plucky(key, obj) {
var sum = 0;
if(typeof obj == "object") {
for(var val in obj) {
if(typeof obj[val] == "object") {
sum += plucky(key, obj[val]);
} else if(val == key) {
sum += obj[val];
}
}
} else if(val == key) {
sum += obj[val];
}
return sum;
}