简体   繁体   English

我需要一个javascript递归函数,当key和json对象传递给这个函数时返回一个值数组

[英]I need a javascript recursive function that return an array of values when key and json object is passed to this function

I need a javascript recursive function that return an array of values when key and JavaScript object is passed to this function. 我需要一个javascript递归函数,当key和JavaScript对象传递给这个函数时返回一个值数组。

Note that the nested JavaScript object has unknown depth. 请注意,嵌套的JavaScript对象具有未知深度。 The function is working fine but it returns duplicates. 该函数工作正常,但它返回重复。

   function getValuesByKey(object, key) {
    var values = [];
    recursiveFx(object);
    function recursiveFx(object) {
      for (var property in object) {
        if (object.hasOwnProperty(property)) {
          if (typeof object[property] == "object") {
           recursiveFx(object[property]);
          } else {
            //found a property which is not an object
            try {
              if (isDefined(object[key])) {
                console.log('Here is the value that is to be pushed',object[key]);
                values.push(object[key]);
              }
            } catch (e) {

            }
          }
        }
      }
    }
    return values;
  } 

Here is the isDefined helper function 这是isDefined辅助函数

function isDefined(variable) {
    try {
    if (typeof(variable) !== 'undefined') return true;
    } catch (e) {
      return false;
    }
  }

Here is an example of JavaScript object: 以下是JavaScript对象的示例:

{
      "children": [{
        "id": "5",
        "parentid": "0",
        "text": "Device Guides",
        "index": "1",
        "children": [{
          "id": "10",
          "index": "0",
          "text": "Grandstream GXP-21XX"
        }, {
          "id": "11",
          "index": "1",
          "text": "Polycom Soundstation/Soundpoint"
        }, {
          "id": "23",
          "parentid": "8",
          "index": "2",
          "text": "New Polycom",
          "children": [{
            "id": "5",
            "parentid": "0",
            "text": "Device Guides",
            "index": "1",
            "children": [{
              "id": "10",
              "index": "0",
              "text": "Grandstream GXP-21XX"
            }, {
              "id": "11",
              "index": "1",
              "text": "Polycom Soundstation/Soundpoint"
            }, {
              "id": "23",
              "index": "2",
              "text": "New Polycom"
            }]
          }, {
            "id": "6",
            "parentid": "0",
            "text": "Pre-Sales Evaluation",
            "index": "0",
            "children": []
          }, {
            "id": "7",
            "parentid": "0",
            "text": "Router Setup Guides",
            "index": "2",
            "children": [{
              "id": "9",
              "index": "0",
              "text": "Sonicwall"
            }, {
              "id": "12",
              "index": "1",
              "text": "Cisco"
            }]
          }]
        }, {
          "id": "6",
          "parentid": "0",
          "text": "Pre-Sales Evaluation",
          "index": "0",
          "children": []
        }, {
          "id": "7",
          "parentid": "0",
          "text": "Router Setup Guides",
          "index": "2",
          "children": [{
            "id": "9",
            "index": "0",
            "text": "Sonicwall"
          }, {
            "id": "12",
            "index": "1",
            "text": "Cisco"
          }]
        }]}]};

When I run this getValuesByKey(jsonObj, 'id'); 当我运行这个getValuesByKey(jsonObj, 'id'); I get the following array: 我得到以下数组:

["5", "5", "5", "5", "10", "10", "10", "11", "11", "11", "23", "23", "23", "23", "5", "5", "5", "5", "10", "10", "10", "11", "11", "11", "23", "23", "23", "6", "6", "6", "6", "7", "7", "7", "7", "9", "9", "9", "12", "12", "12", "6", "6", "6", "6", "7", "7", "7", "7", "9", "9", "9", "12", "12", "12"]

Notice that 5 has been returned 4 times instead of 2 times 请注意,5已返回4次而不是2次

You are checking for the presence of key each time through the loop over the object's properties. 每次通过对象的属性循环检查是否存在key So you are getting as many values as there are properties on the object. 因此,您获得的值与对象上的属性一样多。 So: 所以:

function getValuesByKey(object, key) {
  var values = [];
  recursiveFx(object);
  function recursiveFx(object) {

    if (key in object) values.push(object[key]);
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    for (var property in object) {
      if (object.hasOwnProperty(property)) {
        if (typeof object[property] == "object") {
         recursiveFx(object[property]);
        }
      }
    }
  }
  return values;
} 

Alternative: use JSON.stringify with replacer 替代方案:将JSON.stringify与replacer JSON.stringify使用

Anyway, you can do this more easily with 无论如何,你可以更容易地做到这一点

function getValuesByKey(object, key) {
  var values = [];
  JSON.stringify(object, function(k, v) { 
    if (k === key) values.push(v);
    return v;
  });
  return values;
}

This uses the replacer parameter to JSON.stringify to intercept each key value pair. 这使用JSON.stringifyreplacer参数来拦截每个键值对。 The stringified value itself we don't need and throw away. 字符串化的值本身我们不需要扔掉。

Just an idea of recursion: 只是一个递归的想法:

 var data = { "children": [{ "id": "5", "parentid": "0", "text": "Device Guides", "index": "1", "children": [{ "id": "10", "index": "0", "text": "Grandstream GXP-21XX" }, { "id": "11", "index": "1", "text": "Polycom Soundstation/Soundpoint" }, { "id": "23", "parentid": "8", "index": "2", "text": "New Polycom", "children": [{ "id": "5", "parentid": "0", "text": "Device Guides", "index": "1", "children": [{ "id": "10", "index": "0", "text": "Grandstream GXP-21XX" }, { "id": "11", "index": "1", "text": "Polycom Soundstation/Soundpoint" }, { "id": "23", "index": "2", "text": "New Polycom" }] }, { "id": "6", "parentid": "0", "text": "Pre-Sales Evaluation", "index": "0", "children": [] }, { "id": "7", "parentid": "0", "text": "Router Setup Guides", "index": "2", "children": [{ "id": "9", "index": "0", "text": "Sonicwall" }, { "id": "12", "index": "1", "text": "Cisco" }] }] }, { "id": "6", "parentid": "0", "text": "Pre-Sales Evaluation", "index": "0", "children": [] }, { "id": "7", "parentid": "0", "text": "Router Setup Guides", "index": "2", "children": [{ "id": "9", "index": "0", "text": "Sonicwall" }, { "id": "12", "index": "1", "text": "Cisco" }] }] }] }; function getValuesByKey(object, key) { var values = []; function r(obj) { Object.keys(obj).forEach(function (k) { if (Array.isArray(obj[k])) { obj[k].forEach(r); return; } if (typeof obj[k] === 'object') { r(obj[k]); return; } k === key && !~values.indexOf(obj[k]) && values.push(obj[k]); }); } r(object); return values; } document.write('<pre>' + JSON.stringify(getValuesByKey(data, 'id'), 0, 4) + '</pre>'); 

Ok I got it, there is a bug in your code. 好的我明白了,你的代码中有一个错误。 You should test that key === property when testing if (isDefined(object[key])) { 你应该在测试时测试那个键=== property if(isDefined(object [key])){

Otherwise, you're just adding the matching value whenever you're examining an object that has that value in another property (if that's clear :)) 否则,只要在另一个属性中检查具有该值的对象时,您只需添加匹配值(如果这是明确的:))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM