Inv*_*999 7 arrays select json jq
我有以下 JSON 数组
[
{
"name": "California",
"Data": {
"AB00001": ["Los Angeles", "San Francisco", "Sacramento", "Fresno", "San Jose", "Palo Alto"]
}
},
{
"name": "Oregon",
"Data": {
"CD00002": ["Portland", "Salem", "Hillsboro"]
}
},
{
"name": "Washington",
"Data": {
"EF00003": ["Seattle", "Tacoma", "Spokane", "Bellevue"]
}
}
]
Run Code Online (Sandbox Code Playgroud)
我可以获取jq '.[].Data[] | length'
每个数组的长度,但我需要在对象Length
下创建键Data
并为其分配数据对象中数组的长度。结果应如下所示:
[
{
"name": "California",
"Data": {
"ID00001": ["Los Angeles", "San Francisco", "Sacramento", "Fresno", "San Jose", "Palo Alto"],
"Length": 6
}
},
{
"name": "Oregon",
"Data": {
"ID00002": ["Portland", "Salem", "Hillsboro"],
"Length": 3
}
},
{
"name": "Washington",
"Data": {
"ID00003": ["Seattle", "Tacoma", "Spokane", "Bellevue"],
"Length": 4
}
}
]
Run Code Online (Sandbox Code Playgroud)
这里的问题是,在我的示例中,保存数组的对象名称(Data
在我的示例中)和数组名称本身 ( AB00001/CD00002/EF00003
) 是事先未知的。然而,键的值name
是已知的。另外,数组可能为空,因此在这种情况下,Length
应该为 0。
因此,算法伪代码应该是我所设想的其中之一:
for the whole JSON file,
if the type is an array,
then assign it to the Length key created in the parent object of that array,
next
Run Code Online (Sandbox Code Playgroud)
或者
For the specific value in the name key, select,
if the entry contains an array
create Length key in the array's parent object,
assign the length of the array,
select the next value of the name key
Run Code Online (Sandbox Code Playgroud)
我尝试与 jqwalk
或..
第一种方法一起使用,但没有成功。有哪些替代方案?
解决当前问题(其中 .Data 是一个带有数组值键的单键对象)的解决方案可能很简单:
map( .Data.Length = (.Data[]|length) )
Run Code Online (Sandbox Code Playgroud)
这可以逐步适应更普遍的问题。首先,考虑一下这个概括:
map( .Data |= if length==1 and (.[]|type) == "array"
then .Length = (.[]|length)
else . end )
Run Code Online (Sandbox Code Playgroud)
为了使实际的解决方案更容易理解,让我们定义一个辅助函数:
def addLength:
(first(keys_unsorted[] as $k
| select(.[$k]|type == "object")
| .[$k]
| keys_unsorted[] as $l
| select(.[$l]|type == "array")
| [$k,$l]) // null) as $a
| if $a
then setpath([$a[0],"Length"]; getpath($a)|length)
else .
end;
Run Code Online (Sandbox Code Playgroud)
现在可以使用以下方法编写通用解决方案walk
:
walk(if type == "object" and has("name")
then addLength
else . end)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
11940 次 |
最近记录: |