![](/img/trans.png)
[英]How to filter an array of objects based on value of a element in the Json in JQ
[英]How to filter out a JSON based on list of paths in JQ
給定任意 JSON輸入:
{
"id":"038020",
"title":"Teenage Mutant Ninja Turtles: Out of the Shadows",
"turtles":[
{
"name":"Leonardo",
"mask":"blue"
},
{
"name":"Michelangelo",
"mask":"orange"
},
{
"name":"Donatello",
"mask":"purple"
},
{
"name":"Raphael",
"mask":"red"
}
],
"summary":"The Turtles continue to live in the shadows and no one knows they were the ones who took down Shredder",
"cast":"Megan Fox, Will Arnett, Tyler Perry",
"director":"Dave Green"
}
以及任意 JQ路徑列表,例如[".turtles[].name", ".cast", ".does.not.exist"]
或任何類似格式
如何僅使用列表路徑中包含的信息創建新的JSON? 在這種情況下,預期結果將是:
{
"turtles":[
{
"name":"Leonardo"
},
{
"name":"Michelangelo"
},
{
"name":"Donatello"
},
{
"name":"Raphael"
}
],
"cast":"Megan Fox, Will Arnett, Tyler Perry"
}
我已經看到類似的解決方案,例如使用jq1.5 +中提供的walk函數從JSON中“刪除null
條目”的方法,大致類似:
def filter_list(input, list):
input
| walk(
if type == "object" then
with_entries( select(.key | IN( list )))
else
.
end);
filter_list([.], [.a, .b, .c[].d])
但是它應該以某種方式考慮JSON中的完整路徑。
解決此問題的最佳方法是什么?
如果$ paths包含一個顯式jq路徑數組(例如[ ["turtles", 0, "name"], ["cast"]])
,則最簡單的方法是使用以下過濾器:
. as $in
| reduce $paths[] as $p (null; setpath($p; $in | getpath($p)))
為了能夠處理擴展路徑表達式,例如[“ turtles”,[],“ name”],其中[]
的目的是在turtles
數組的索引范圍內,我們將定義以下輔助函數:
def xpath($ary):
. as $in
| if ($ary|length) == 0 then null
else $ary[0] as $k
| if $k == []
then range(0;length) as $i | $in[$i] | xpath($ary[1:]) | [$i] + .
else .[$k] | xpath($ary[1:]) | [$k] + .
end
end ;
為了說明起見,讓我們還定義:
def paths($ary): $ary[] as $path | xpath($path);
然后使用給定的輸入,表達式:
. as $in
| reduce paths([ ["turtles", [], "name"], ["cast"]]) as $p
(null; setpath($p; $in | getpath($p)) )
產生如下所示的輸出。
path
值得指出的是,處理諸如“ .turtles []。name”之類的表達式的一種方法是使用內置過濾器path/1
。
例如:
# Emit a stream of paths:
def paths: path(.turtles[].name), ["cast"];
. as $in
| reduce paths as $p (null; setpath($p; $in | getpath($p)))
{
"turtles": [
{
"name": "Leonardo"
},
{
"name": "Michelangelo"
},
{
"name": "Donatello"
},
{
"name": "Raphael"
}
],
"cast": "Megan Fox, Will Arnett, Tyler Perry"
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.