json jq中的内联接

6yjfywim  于 2023-01-18  发布在  其他
关注(0)|答案(2)|浏览(141)

使用给定的输入,我需要将tweets数组中真正的"user"值与users数组中的id连接起来,并将users数组对象显示为tweets数组的一部分

    • 输入:**
{
  "tweets": [
    {
      "tweet": "Hey, i gonna release GPT4 soon",
      "user": 1
    },
    {
      "tweet": "We have launched falcon 10 yesterday, it was awesome, one step closer to Mars",
      "user": 2
    },
    {
      "tweet": "Databar acquires Statista.com, great news coming out",
      "user": 3
    },
    {
      "tweet": "Gpt4 is available",
      "user": 1
    }
  ],
  "users": [
    { "id": 1, "name": "a" },
    { "id": 2, "name": "b" },
    { "id": 3, "name": "c" }
  ]
}
    • 产出**
[
  {
    "tweet": "Hey, i gonna release GPT4 soon",
    "user": {
      "id": 1,
      "name": "a"
    }
  },
  {
    "tweet": "We have launched falcon 10 yesterday, it was awesome, one step closer to Mars",
    "user": {
      "id": 2,
      "name": "b"
    }
  },
  {
    "tweet": "Databar acquires Statista.com, great news coming out",
    "user": {
      "id": 3,
      "name": "c"
    }
  },
  {
    "tweet": "Gpt4 is available",
    "user": {
      "id": 1,
      "name": "a"
    }
  }
]

我尝试使用if条件先查找相等的值,但它会遍历整个数组,因此无法获得users数组中ID也相等的值的具体值

ni65a41a

ni65a41a1#

构建一个INDEX,然后使用它来Map您的tweet:

INDEX(.users[]; .id) as $idx | .tweets | map({ tweet, user: $idx[.user|tostring] })

或者直接使用JOIN

[JOIN(INDEX(.users[]; .id); .tweets[]; .user|tostring; .[0] + { user: .[1] })]

你也可以用一种低效的方法来做,通过迭代来找到正确的用户:

.users as $users
| .tweets
| map({ tweet, user: (.user as $user | $users[] | select(.id == $user))})
fafcakar

fafcakar2#

@knittl使用INDEX的解决方案是好的,除非存在id的“冲突”(例如,如果.id可以同时是1"1")。
为避免冲突并允许其他类型的.id值,可以使用SAFE_INDEXlookup,定义如下:

def SAFE_INDEX(stream; idx_expr):
  reduce stream as $row ({};
    ($row|idx_expr) as $ix
    | .[$ix|type][$ix|tostring] = $row);

def lookup($value):
   .[$value|type] as $t
   | if ($t|type) == "object" then $t[$value|tostring] else null end;

因此,这个问题的一般解决方案如下所示:

SAFE_INDEX(.users[]; .id) as $idx 
| .tweets
| map({ tweet, user: (.user as $user | $idx |lookup($user)) })

相关问题