【问题标题】:Nested Key/Value Structures in JSONJSON 中的嵌套键/值结构
【发布时间】:2016-07-21 07:41:51
【问题描述】:

我从服务中获得以下 JSON 结构:

{
    "prop": [
        {
            "key": "FOO",
            "value": "Foo is wonderfull, foo is great"
        },
        {
            "key": "BAR",
            "value": "Bar is bad, really bad"
        }
    ]
}

我需要一个函数,它作为参数,例如BAR 并输出“Bar is bad,..”,我该如何实现?欢迎使用 Lodash/下划线或 VanillaJS。

【问题讨论】:

  • 您可以遍历您的prop 数组并在每次交互中获取key 属性,将其与传递给您的函数的参数进行比较,如果匹配则返回value 属性。跨度>

标签: javascript json underscore.js lodash


【解决方案1】:

你可以使用Array.find找到需要的对象,然后返回它的值

var d = {
  "prop": [{
    "key": "FOO",
    "value": "Foo is wonderfull, foo is great"
  }, {
    "key": "BAR",
    "value": "Bar is bad, really bad"
  }]
}

function FindValue(value) {
  var _tmp = d.prop.find(function(o) {
    return o.key === value
  });
  return _tmp ? _tmp.value : "No object found";
}

console.log(FindValue("BAR"));
console.log(FindValue("BAR1"));
console.log(FindValue("FOO"));

编辑 1

正如@Benny Bottema 所建议的,Array.find 存在兼容性问题。您可以添加polyfill,也可以使用其他方法,例如Array.filterArray.forEach,但请注意,IE8 不支持这些方法。

如果要使其与所有浏览器兼容,则应使用forfor..in,因为它们是跨浏览器的标准。

对于版本

var d = {
  "prop": [{
    "key": "FOO",
    "value": "Foo is wonderfull, foo is great"
  }, {
    "key": "BAR",
    "value": "Bar is bad, really bad"
  }]
}

function FindValue(value) {
  for (var i=0;i<d.prop.length;i++){
    if(d.prop[i].key === value) return d.prop[i].value;
  }
}

console.log(FindValue("BAR"));
console.log(FindValue("BAR1"));
console.log(FindValue("FOO"));

for..in 版本

注意,for..in 更适合循环对象的键。

var d = {
  "prop": [{
    "key": "FOO",
    "value": "Foo is wonderfull, foo is great"
  }, {
    "key": "BAR",
    "value": "Bar is bad, really bad"
  }]
}

function FindValue(value) {
  for (var i in d.prop){
    if(d.prop[i].key === value) return d.prop[i].value;
  }
}

console.log(FindValue("BAR"));
console.log(FindValue("BAR1"));
console.log(FindValue("FOO"));

for..of 版本

如果你使用的是 ES6,那么你甚至可以尝试for..of

var d = {
  "prop": [{
    "key": "FOO",
    "value": "Foo is wonderfull, foo is great"
  }, {
    "key": "BAR",
    "value": "Bar is bad, really bad"
  }]
}

function FindValue(value) {
  for (var _o of d.prop){
    if(_o.key === value) return _o.value;
  }
}

console.log(FindValue("BAR"));
console.log(FindValue("BAR1"));
console.log(FindValue("FOO"));

参考文献

【讨论】:

【解决方案2】:
var filteredArray = { "prop": [{ "key": "FOO", "value": "Foo is wonderfull, foo is great" }, { "key": "BAR", "value": "Bar is bad, really bad" }] };
function getByKey(findKey,filteredArray){
    if(filteredArray.length){
            var result = filteredArray.filter(function(x){
                return x.key === findKey
            });
            if(result && result.length){return result[0].value}
    }
}
getByKey('BAR',filteredArray.prop)

但该函数只会返回第一个过滤的对象的值;

【讨论】:

    【解决方案3】:

    现代纯javascript:

    function getValue(theObject, keyValue) {
      return theObject.prop
        .filter(function(x){ // find all elements with the wanted key
          return x.key == keyValue;
        })
        .map(function(x){ // return only the value
          return x.value;
        })[0]; // Assuming no duplicate keys just return first item
    }
    

    注意:数组方法.filter().map() 返回数组。

    老派 for 循环:

    function getValue(theObject, keyValue) {
      var p = theObject.prop;
    
      for (var i=0; i<p.length; i++) {
        var item = p[i];
        if (item.key == keyValue) {
          return item.value;
        }
      }
    }
    

    有趣的是,这比上面的第一种方法更快,因为它在找到匹配项后立即停止处理 prop 数组。

    【讨论】:

    • 如果您要返回 [0] 元素,为什么首先要返回 map。只需检查对象是否存在并返回_temp[0].value
    • 我正在尝试使用 Angular2 + Observables 的解决方案,但无法获得“FOO”:plnkr.co/edit/JMvZ2pNhjpzS7bG6erWb?p=preview
    【解决方案4】:

    我是用 JAVASCRIPT 写的:

    var d = {
      "prop": [{
        "key": "FOO",
        "value": "Foo is wonderfull, foo is great"
      }, {
        "key": "BAR",
        "value": "Bar is bad, really bad"
      }]
    }
    
    obj = d;
    parm = 'BAR'
    for (item in obj["prop"]) {
      if (parm == item['key']) {
        console.log(item['value'])
      }
    }

    查看步骤:-

    • 首先将 JSON 解析为 Object
    • 然后遍历“prop”
    • 将键与参数(“BAR”)进行比较
    • 如果匹配打印值

    【讨论】:

    • 这不起作用,因为 for..in 循环迭代对象的属性。如果是数组,则每次迭代中的item 将是字符串中的数字索引,例如"0""1" ,而不是数组中的实际对象
    • @Arkantos 这里的 prop 是一个数组,它工作得很好。试试看。如果它不起作用,请投票。
    • @RakeshKumar 刚刚更新了您的答案。只需检查并进行必要的更改。同样,Arkantos 是正确的。应该是obj["prop"][item]["key"] 或使用for...of
    • @RakeshKumar.. 它不起作用。这是带有您的代码的pen。就像我说的,它打印 0 和 1。
    • @Arkantos 我猜他尝试过for..of,但在写作时,他输入了for..in
    【解决方案5】:

    您可以使用lodash#find按键获取值。

    function getValueByKey(array, key) {
      return (_.find(array, { key: key }) || {}).value;
    }
    
    var result = getValueByKey(data.prop, 'BAR');
    

    var data = {
        "prop": [
            {
                "key": "FOO",
                "value": "Foo is wonderfull, foo is great"
            },
            {
                "key": "BAR",
                "value": "Bar is bad, really bad"
            }
        ]
    };
    
    function getValueByKey(array, key) {
      return (_.find(array, { key: key }) || {}).value;
    }
    
    var result = getValueByKey(data.prop, 'BAR');
    
    console.log(result);
    &lt;script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"&gt;&lt;/script&gt;

    【讨论】:

      【解决方案6】:

      简单。

      洛达什

      var data = {
          "prop": [
              {
                  "key": "FOO",
                  "value": "Foo is wonderfull, foo is great"
              },
              {
                  "key": "BAR",
                  "value": "Bar is bad, really bad"
              }
          ]
      }
      
      function getValueForKey(key) {
        return _.result(_.find(data.prop, { key: key }), 'value') || "unknown key: " + key;
      }
      
      document.write(getValueForKey("FOO") + "<br/>");
      document.write(getValueForKey("BAR") + "<br/>");
      document.write(getValueForKey("FOOBAR"));
      &lt;script src="https://cdn.rawgit.com/lodash/lodash/4.13.1/dist/lodash.core.min.js"&gt;&lt;/script&gt;

      下划线

      var data = {
          "prop": [
              {
                  "key": "FOO",
                  "value": "Foo is wonderfull, foo is great"
              },
              {
                  "key": "BAR",
                  "value": "Bar is bad, really bad"
              }
          ]
      }
      
      function getValueForKey(key) {
        return _.result(_.find(data.prop, { key: key }), 'value', "unknown key: " + key);
      }
      
      document.write(getValueForKey("FOO") + "<br/>");
      document.write(getValueForKey("BAR") + "<br/>");
      document.write(getValueForKey("FOOBAR"));
      &lt;script src="http://underscorejs.org/underscore.js"&gt;&lt;/script&gt;

      纯javascript(使用filter,主流浏览器支持)

      var data = {
          "prop": [
              {
                  "key": "FOO",
                  "value": "Foo is wonderfull, foo is great"
              },
              {
                  "key": "BAR",
                  "value": "Bar is bad, really bad"
              }
          ]
      }
      
      function getValueForKey(key) {
        var prop = data.prop.filter(function(prop) { return prop.key === key})[0];
        return prop ? prop.value : "unknown key: " + key;
      }
      
      document.write(getValueForKey("FOO") + "<br/>");
      document.write(getValueForKey("BAR") + "<br/>");
      document.write(getValueForKey("FOOBAR"));

      纯javascript(使用find,目前主要与polyfill一起使用)

      var data = {
          "prop": [
              {
                  "key": "FOO",
                  "value": "Foo is wonderfull, foo is great"
              },
              {
                  "key": "BAR",
                  "value": "Bar is bad, really bad"
              }
          ]
      }
      
      function getValueForKey(key) {
        var prop = data.prop.find(function(prop) { return prop.key === key });
        return prop ? prop.value : "unknown key: " + key;
      }
      
      document.write(getValueForKey("FOO") + "<br/>");
      document.write(getValueForKey("BAR") + "<br/>");
      document.write(getValueForKey("FOOBAR"));
      <script>
      // polyfill from https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/find#Polyfill
      if (!Array.prototype.find) {
        Array.prototype.find = function(predicate) {
          if (this == null) {
            throw new TypeError('Array.prototype.find called on null or undefined');
          }
          if (typeof predicate !== 'function') {
            throw new TypeError('predicate must be a function');
          }
          var list = Object(this);
          var length = list.length >>> 0;
          var thisArg = arguments[1];
          var value;
      
          for (var i = 0; i < length; i++) {
            value = list[i];
            if (predicate.call(thisArg, value, i, list)) {
              return value;
            }
          }
          return undefined;
        };
      }
      </script>

      纯 javascript(使用老式 for 循环)

      var data = {
          "prop": [
              {
                  "key": "FOO",
                  "value": "Foo is wonderfull, foo is great"
              },
              {
                  "key": "BAR",
                  "value": "Bar is bad, really bad"
              }
          ]
      }
      
      function getValueForKey(key) {
        for (var i = 0; i < data.prop.length; i++) {
          if (data.prop[i].key === key) {
            return data.prop[i].value;
          }
          return "unknown key: " + key;
        }
      }
      
      document.write(getValueForKey("FOO") + "<br/>");
      document.write(getValueForKey("BAR") + "<br/>");
      document.write(getValueForKey("FOOBAR"));

      【讨论】:

        【解决方案7】:

        如果找到值,您可以使用Array#some 并结束迭代。

        function getValue(array, key) {
            var value;
            array.some(function (a) {
                if (a.key === key) {
                    value = a.value;
                    return true;
                }
            });
            return value;
        }
        
        var object = { "prop": [{ "key": "FOO", "value": "Foo is wonderfull, foo is great" }, { "key": "BAR", "value": "Bar is bad, really bad" }] };
        
        console.log(getValue(object.prop, 'BAR'));

        ES6 与 Array#find

        function getValue(array, key) {
            return (array.find(a => a.key === key) || {}).value;
        }
        
        var object = { "prop": [{ "key": "FOO", "value": "Foo is wonderfull, foo is great" }, { "key": "BAR", "value": "Bar is bad, really bad" }] };
        
        console.log(getValue(object.prop, 'BAR'));

        【讨论】:

        • @Rajesh,没错。因此默认对象:(array.find(a =&gt; a.key === key) || {}).value;
        猜你喜欢
        • 2016-08-19
        • 1970-01-01
        • 1970-01-01
        • 2020-12-17
        • 1970-01-01
        • 2014-06-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多