首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何根据第二个值以及第三个值的出现次数来设置JSON值

如何根据第二个值以及第三个值的出现次数来设置JSON值
EN

Stack Overflow用户
提问于 2018-08-04 18:13:04
回答 2查看 73关注 0票数 1

初始files.json文档状态:

代码语言:javascript
复制
[
  {
    "filename": "a",
    "dir": "foo",
    "type": "unknown"
  },
  {
    "filename": "b",
    "dir": "foo",
    "type": "unknown"
  },
  {
    "filename": "c",
    "dir": "bar",
    "type": "unknown"
  },
  {
    "filename": "a",
    "dir": "bar",
    "type": "unknown"
  }
]

当"filename“值在文档中只出现一次时,"type”值将只依赖于"dir“值:"dir" == "foo" --> "type" = 0"dir" == "bar" --> "type" = 1

当"filename“值同时存在于"foo”和"bar“目录中时,”==“的值必须为2,如下所示:

代码语言:javascript
复制
[
  {
    "filename": "a",
    "dir": "foo",
    "type": "2"
  },
  {
    "filename": "b",
    "dir": "foo",
    "type": "0"
  },
  {
    "filename": "c",
    "dir": "bar",
    "type": "1"
  },
  {
    "filename": "a",
    "dir": "bar",
    "type": "2"
  }
]

"dir“值将始终限制为"foo”或"bar“值的两个可能替代值,并且永远不会为空。

即使是"filename“值也会被设置,因为这些都是真正的文件,所以在文档中最多只能出现两次。

我想在Linux的Bash脚本中运行jq 1.5 (2015年8月16日稳定版)来实现这一点。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-08-05 11:20:05

这是一个类似@CharlesDuffy的解决方案,但更简短,更具"jq-ish":

代码语言:javascript
复制
(reduce .[] as $x ({}; .[$x.filename] += [$x.dir])
 | map_values(unique)) as $dirs
| map( $dirs[.filename] as $d
       | .type |= if $d|length > 1 then 2
                  elif $d[0] == "bar" then 1
                  else 0
                  end)

使用catalog/3

在通用助手函数catalog/3的帮助下

代码语言:javascript
复制
def catalog(s; keyp; valuep):
   reduce s as $x ({}; (.[$x|keyp|tostring]) += [$x|valuep]);

解决方案变得更具可读性:

代码语言:javascript
复制
(catalog(.[]; .filename; .dir) | map_values(unique)) as $dirs
| map( $dirs[.filename] as $d
       | .type |= if $d|length > 1 then 2
                  elif $d[0] == "bar" then 1
                  else 0
                  end)
票数 3
EN

Stack Overflow用户

发布于 2018-08-05 00:58:36

一种方法是使用group_by。在下面的示例中,group_by使用得很简单,因此数组中最终结果的排序由.filename决定;如果排序不令人满意,可以使用相同的技术构造一个查找表,然后对原始数组使用该表。

代码语言:javascript
复制
[group_by(.filename)[]
 | (map(.dir) 
    | unique
    | if length>1 then length
      elif .[0] == "foo" then 0
      elif .[0] == "bar" then 1
      else .[0]          # just in case
      end) as $type
    | (.[] + {type: $type} ) ]

输出

代码语言:javascript
复制
[
  {
    "filename": "a",
    "dir": "foo",
    "type": 2
  },
  {
    "filename": "a",
    "dir": "bar",
    "type": 2
  },
  {
    "filename": "b",
    "dir": "foo",
    "type": 0
  },
  {
    "filename": "c",
    "dir": "bar",
    "type": 1
  }
]
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51684565

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档