首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类似于jq中的sql联接

类似于jq中的sql联接
EN

Stack Overflow用户
提问于 2014-08-05 04:37:42
回答 3查看 1.4K关注 0票数 2

我有以下的json:

代码语言:javascript
复制
[
  {"id": "1", "type": "folder", "title": "folder-1"},
  {"id": "2", "type": "folder", "title": "folder-2"},
  {"id": "3", "type": "item", "title": "item-1", "folder": "1"},
  {"id": "4", "type": "item", "title": "item-2", "folder": "2"},
  {"id": "5", "type": "item", "title": "item-3"}
]

基本上,我需要使用jq生成这个输出,这类似于sql的结果:

代码语言:javascript
复制
[
  {"type": "item", "title": "item-1", "folder": "folder-1"},
  {"type": "item", "title": "item-2", "folder": "folder-2"},
  {"type": "item", "title": "item-3"}
]

有什么想法吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-08-05 19:18:15

试试这个过滤器:

代码语言:javascript
复制
map(
    (select(.type=="item") | { key: .folder, value: { type, title } }),
    (select(.type=="folder") | { key: .id, value: { folder: .title } })
)
| group_by(.key)
| map(
    (map(select(.key != null) | .value) | add)
    // map(.value)[]
)

你得把它分成几步。

  1. 获取项目和文件夹,并为每个项目获取您感兴趣的值,并为其分配一个与之关联的键。 映射((选择(.type==“item”)\{ key:.folder,value:{ type,title }),(select(.type==“.id”)\{ key:.id,value:{文件夹:.title } })
  2. 按键分组 group_by(.key)
  3. 然后组合具有键(文件夹)的值,否则合并值。 @ map( (map(select(.key != null)可比.value) \/ map(.value)[] )
票数 1
EN

Stack Overflow用户

发布于 2014-08-05 12:41:55

代码语言:javascript
复制
jq 'map(select(has("folder") or (.["title"] | startswith("item"))) | del(.id))' sample_file

输出:

代码语言:javascript
复制
[
  {
    "type": "item",
    "title": "item-1",
    "folder": "1"
  },
  {
    "type": "item",
    "title": "item-2",
    "folder": "2"
  },
  {
    "type": "item",
    "title": "item-3"
  }
]
票数 0
EN

Stack Overflow用户

发布于 2017-08-25 15:10:28

下面是另一种解决方案,通过将数据分离为两个对象( $folders$items ),然后构造所需的结果。

代码语言:javascript
复制
  (
    reduce map(select(.type == "folder"))[] as $f (
      {}
    ; .[$f.id] = $f
    )
  ) as $folders

| (
    reduce map(select(.type == "item"))[] as $i (
      {}
    ; .[$i.id] = $i
    ) 
  ) as $items

| [
      $items[]
    | {type, title, folder}
    | if .folder == null then del(.folder) else .folder = $folders[.folder].title end
  ]

如果您的jq版本有指数/2

代码语言:javascript
复制
def INDEX(stream; idx_expr):
  reduce stream as $row ({};
    .[$row|idx_expr|
      if type != "string" then tojson
      else .
      end] |= $row);

这可以简化为

代码语言:javascript
复制
  INDEX(.[] | select(.type == "folder"); .id) as $folders
| INDEX(.[] | select(.type == "item"); .id) as $items
| [
      $items[]
    | {type, title, folder}
    | if .folder == null then del(.folder) else .folder = $folders[.folder].title end
  ]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25131293

复制
相关文章

相似问题

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