【问题标题】:Find JSON value for a specific key in Nested JSON with unstructured keys using underscore使用下划线使用非结构化键在嵌套 JSON 中查找特定键的 JSON 值
【发布时间】:2017-07-20 00:43:43
【问题描述】:

我有一个嵌套的 JSON 对象,我想在其中找到特定键的值。假设 JSON 是这样的:

var data={

       name:"dsd",
       work: "abcd",
       address:{
          street:"wewe 32",
          apt: 12,
          city: "ca",
          geo:{
             lat: 23.4332,
             lng: 132.232
          },
          hobbies:["play","sing"]
       }        

 }

现在如果我想找到“city”的值,那么它应该给我“ca”,如果我想找到“lng”的值,那么它应该返回 132.232。如果我想找到“爱好”的价值,它应该给我[玩,唱歌]。我怎样才能得到这个?使用下划线或 lodash 的解决方案将不胜感激。

【问题讨论】:

  • 假设我想找到 city 的值然后 var city =_.values(_.pick(data, 'city'));给出空数组
  • 我也用过 _.pluck(data, 'city');但给出 null
  • 尝试使用_.get(data, 'address.city')
  • 这是个问题。我不知道“城市”在 JSON 中的位置。它是嵌套的。我只有两个输入,一个是 JSON 对象,另一个是 key。

标签: javascript json underscore.js lodash


【解决方案1】:

您可以通过递归迭代lodash#some 来实现此目的。检查下面的 cmets 以获得指导。

function getValueByKey(object, key) {
  // The resulting value of a matched key
  var result;

  // Use _.some as an iterator, to stop the iteration
  // and recursion once a match is found. Also, name 
  // the predicate function for recursion.
  _.some(object, function matchKey(value, $key) {
    if ($key === key) { // is key a match?
      result = value; // set the result
      return true; // this stops the iteration and recursion
    } else if (_.isObject(value)) { // is value an object?
      // recursively match the keys all over again
      return _.some(value, matchKey);
    }
  });

  // return matched result
  return result;
}

var data = {
  name: "dsd",
  work: "abcd",
  address: {
    street: "wewe 32",
    apt: 12,
    city: "ca",
    geo: {
      lat: 23.4332,
      lng: 132.232
    },
    hobbies: ["play", "sing"]
  }
};

function getValueByKey(object, key) {
  // The resulting value of a matched key
  var result;

  // Use _.some as an iterator, to stop the iteration
  // and recursion once a match is found. Also, name 
  // the predicate function for recursion.
  _.some(object, function matchKey(value, $key) {
    if ($key === key) { // is key a match?
      result = value; // set the result
      return true; // this stops the iteration and recursion
    } else if (_.isObject(value)) { // is value an object?
      // recursively match the keys all over again
      return _.some(value, matchKey);
    }
  });

  // return matched result
  return result;
}

console.log('hobbies:', getValueByKey(data, 'hobbies'));
console.log('geo:', getValueByKey(data, 'geo'));
console.log('lng:', getValueByKey(data, 'lng'));
.as-console-wrapper {
  min-height: 100%;
  top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

替代方案:这是一个非递归的 vanilla javascript 解决方案:

function getValueByKey(object, key) {

  // simulate recursion by stacking
  var stack = [object];
  var current, index, value;

  // keep iterating until the stack is empty
  while (stack.length) {
    // take the head of the stack
    current = stack.pop();
    // iterate over the current object
    for (index in current) {
      // get value of the iterated object
      value = current[index];
      // is it a match?
      if (key === index) {
        return value; // return the matched value
      } 
      // value must be an object and not a null value
      // to be subject for the next stack iteration
      else if (value !== null && typeof value === 'object') {
        // add this value in the stack
        stack.unshift(value);
      }
    }
  }

}

var data = {
  name: "dsd",
  work: "abcd",
  address: {
    street: "wewe 32",
    apt: 12,
    city: "ca",
    geo: {
      lat: 23.4332,
      lng: 132.232
    },
    hobbies: ["play", "sing"]
  }
}

function getValueByKey(object, key) {

  // simulate recursion by stacking
  var stack = [object];
  var current, index, value;

  // keep iterating until the stack is empty
  while (stack.length) {
    // take the head of the stack
    current = stack.pop();
    // iterate over the current object
    for (index in current) {
      // get value of the iterated object
      value = current[index];
      // is it a match?
      if (key === index) {
        return value; // return the matched value
      } 
      // value must be an object and not a null value
      // to be subject for the next stack iteration
      else if (value !== null && typeof value === 'object') {
        // add this value in the stack
        stack.unshift(value);
      }
    }
  }

}

console.log('hobbies:', getValueByKey(data, 'hobbies'));
console.log('geo:', getValueByKey(data, 'geo'));
console.log('lng:', getValueByKey(data, 'lng'));
.as-console-wrapper { min-height: 100%; top: 0; }

【讨论】:

    猜你喜欢
    • 2017-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    • 1970-01-01
    • 2016-05-25
    • 1970-01-01
    • 2022-01-13
    相关资源
    最近更新 更多