簡體   English   中英

獲取JavaScript對象中具有匹配鍵的所有值的總和?

[英]Get a sum of all values that have matching keys in a JavaScript Object?

我試圖做一個函數,將基於鍵求和。 這是一個示例對象:

{
  "US": {
    "q": 1,
    "Atlanta": {
      "q": 2
    },
    "Boston": {
      "q": 1
    }
}

我希望能夠調用類似以下的函數:

var sum = plucky("q", obj);
// sum === 4;

我正在使用的函數,我相信我從過去某個地方的SO帖子中發現, 幾乎可以完成正確的事情:

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和我自己的未來很有用。

香草JavaScript(來自dfsq)

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;
}

Lodash(Underscore?)功能示例(通過Bergi)

function pluckDeepKey(key, obj) {
  return _.reduce(obj, function(a, v) {
    return a + (_.isObject(v) ? pluckDeepKey(key, v) : 0);
  }, _.has(obj, key) ? obj[key] : 0);
}

Mori.js和Immutable.js功能示例

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
  );
}

我認為普通的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); 

但是,由於: 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始終返回一個數字,空的錯誤應該只是0 )。 如果需要,還可以將reducemap一起加入

function pluckDeepKey(key, obj) {
  return _.reduce(obj, function(a, v) {
    return a + (_.isObject(v) ? pluckDeepKey(key, v) : 0);
  }, _.has(obj, key) ? obj[key] : 0);
}

除了其他答案,您還可以使用內置的所有功能,也可以使用遞歸功能,以實現更多功能:

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)
}

您可以使用如下形式:

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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM