【问题标题】:filter certain (sub) keys from a JSON value从 JSON 值中过滤某些(子)键
【发布时间】:2020-08-22 14:34:16
【问题描述】:

我有一个相对较大的 JSON 文件,其中包含大量我不需要的数据。

我想只保留我感兴趣的元素,但我想保留一般结构。

[
  {
    "name"  : "foo",
    "age"   : 12,
    "weight": 23, 
    "colors": {
      "head":{
        "hair": "blue",
        "eyes": "green"
      }
    }
  },
  {
    "name"  : "bar",
    "age"   : 42,
    "weight": 54, 
    "colors": {
      "head":{
        "hair": "blue",
        "eyes": "blue"
      }
    }
  },
  {
    "name"  : "baz",
    "age"   : 65,
    "weight": 439, 
    "colors": {
      "head":{
        "hair": "green",
        "eyes": "red"
      }
    }
  }

]

输出应如下所示:

{
  "name": "foo",
  "colors": {
    "head": {
      "eyes": "green"
    }
  }
}
{
  "name": "bar",
  "colors": {
    "head": {
      "eyes": "blue"
    }
  }
}
{
  "name": "baz",
  "colors": {
    "head": {
      "eyes": "red"
    }
  }
}

我的实际输入对象每个顶级对象有大约 100 个叶键,我需要大约 10 个叶键,而且几乎所有叶键都位于层次结构的不同级别。

我研究了一些 json 处理 API(例如 javascript、lodash 和 jq),但找不到这样的机制。它们主要依赖于以简单语法创建新对象,需要从头开始构造对象。

喜欢:

jq '[.[]| {name: .name, colors:{head:{eyes: .colors.head.eyes}}}]'

层次结构很深,这有点混乱。

我是否错过了一些可以更轻松地指定深层对象键的东西,例如:

.[] | {name: .name, colors.head.eyes = .colors.head.eyes}

或者更方便一些:一些子键过滤机制,比如

.[] | filteKeys(["name", "colors.head.eyes"])

我更喜欢一些支持命令行的程序,所以我尝试使用 JQ。

【问题讨论】:

    标签: json jq


    【解决方案1】:

    一些子键过滤机制可以如下实现。

    def pick(paths):
      . as $in
      | reduce path(paths) as $path (null;
        setpath($path; $in | getpath($path))
      );
    

    你可以像这样使用它:

    .[] | pick(.name, .colors.head.eyes)
    

    demo at jqplay.org

    【讨论】:

      【解决方案2】:

      那里有很多图书馆。我们真的很喜欢object-fields(建立在object-scan 之上,所以速度很快)。如果您想支持 fields 参数语法,那就太好了。无论如何,这是您如何回答您的问题

      // const objectFields = require('object-fields');
      
      const input = [{ name: 'foo', age: 12, weight: 23, colors: { head: { hair: 'blue', eyes: 'green' } } }, { name: 'bar', age: 42, weight: 54, colors: { head: { hair: 'blue', eyes: 'blue' } } }, { name: 'baz', age: 65, weight: 439, colors: { head: { hair: 'green', eyes: 'red' } } }];
      
      const retain = objectFields.Retainer(['name', 'colors.head.eyes']);
      retain(input);
      console.log(input);
      // => [ { name: 'foo', colors: { head: { eyes: 'green' } } }, { name: 'bar', colors: { head: { eyes: 'blue' } } }, { name: 'baz', colors: { head: { eyes: 'red' } } } ]
      .as-console-wrapper {max-height: 100% !important; top: 0}
      <script src="https://bundle.run/object-fields@2.0.19"></script>

      免责声明:我是object-fields的作者

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-15
        • 1970-01-01
        • 1970-01-01
        • 2021-11-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多