这是我的JSON:
{
"A":[
{
"AT":"text"
},
{
"AT":"text2"
}
],
"B":[
{
"name":"text",
"power":10
},
{
"name":"text1",
"power":20
},
{
"name":"text2",
"power":40
}
]
}
我希望所有B元素都具有与A元素相同的名称。因此,在这种情况下,结果将为['text',10,'text2',40]
。我尝试使用此查询[.B[] | [.name , .power][]] | map(in([.A[].AT]))
,但无法正常工作,这使我出错:
jq:错误(在23处):无法索引字符串为“ A”的字符串 退出状态5
我不知道如何解决它,但我认为它与父节点有关,它无法识别in函数中的嵌套查询。那么是否有可能用这种语言进行嵌套查询,以及如何在其他情况下(如其他函数或管道的其他情况)处理嵌套查询的问题?
PS:我在JAVASCRIPT(node.js)中工作
新问题,我有以下查询:
( .Move | map({(.name): {accuracy : .url.accuracy, damage_class: .url.damage_class.name, power : .url.power, priority: .url.priority, target: .url.target.name, type: .url.type.name, null}}) | add ) as $b | .results | select(.name=="bulba") | map(.url.moves[].move.name | [., $b[.][]]) | add
并且在没有select(.name=="bulba")
jq:错误(在:158):无法索引字符串为“名称”的数组
我应该用这个显示JSON吗?(因为它比上一个大一点) 但这是从这里开始的:
{
"results":[
{
"name":"bulba",
"url":{
"moves":[
{
"move":{
"name":"flamiche"
}
}
]
}
},
{
"name":"sala",
"url":{
"moves":[
{
"move":{
"name":"DAMSSSS"
}
}
]
}
}
],
"Move":[
{
"name":"flamiche",
"url":{
"accuracy":50,
"damage_class":{
"name":"physical"
},
"power":50,
"priority":0,
"target":{
"name":"foe"
},
"type":{
"name":"fire"
}
}
},
{
"name":"DAMSSSS",
"url":{
"accuracy":90,
"damage_class":{
"name":"status"
},
"power":null,
"priority":2,
"target":{
"name":"self"
},
"type":{
"name":"grass"
}
}
}
]
}
答案 0 :(得分:1)
如果要获取B
上的所有A
对象,则可以使用Set
和concat
创建具有所有A值的对象。使用filter
过滤对象B
var obj = {"A":[{"AT":"text"},{"AT":"text2"}],"B":[{"name":"text","power":10},{"name":"text1","power":20},{"name":"text2","power":40}]}
var allAs = new Set([].concat(...obj.A.map(o => Object.values(o))));
var result = obj.B.filter(o => allAs.has(o.name));
console.log(result);
您还可以将flatMap
(在节点11.0.0上可用)用作:
var obj = {"A":[{"AT":"text"},{"AT":"text2"}],"B":[{"name":"text","power":10},{"name":"text1","power":20},{"name":"text2","power":40}]}
var allAs = new Set(obj.A.flatMap(o => Object.values(o)));
var result = obj.B.filter(o => allAs.has(o.name));
console.log(result);
答案 1 :(得分:1)
您正在将[.B[] | [.name , .power][]]
的产品(将是由字符串组成的数组)传送到map(in([.A[].AT]))
,即输入被更改并且{{1} }丢失了,您正在尝试从这些字符串中获取.A
。这不是唯一的问题,而是导致该错误的原因。您最好这样做:
.A[].AT
如果使用( .B | map({(.name): .power}) | add ) as $b
| .A | map(.AT | [., $b[.]]) | add
输入的内容太大,则可以获得更好的效果:
reduce
关于第二个问题,通过将( reduce .B[] as $b ({}; . + ($b | {(.name): .power})) ) as $b
| reduce .A[].AT as $a ([]; . + [$a, $b[$a]])
(对象数组)传递给results
,因为错误消息指出您正在尝试使用字符串对数组进行索引。要过滤select(.name=="bulba")
下的对象,请像这样将results
移到select
中:
map
答案 2 :(得分:0)
如果对替代(非jq)解决方案感兴趣,可以采用一种新颖的方法来实现-使用基于步行路径的Unix实用程序 jtc
,该逻辑主要是编码到JSON树中:
bash $ <file.json jtc -x'[A][:][AT]<at>v[^0][B][name]:<at>s' -y' ' -y'[-1][power]' -jr
[ "text", 10, "text2", 40 ]
bash $
步行路径(-w
)细分:
[A][:][AT]<at>v
-从根开始,通过标签A
地址JSON,然后在其中记录([:]
),然后为每个记录地址标签AT
记忆在名称空间at
[^0][B][name]:<at>s
-重置返回的根([^0]
),通过标签B
地址JSON,然后(在B
中)搜索存储在命名空间{中的值{1}}的标签为at
-这样,它将找到A中所有发生在B中的条目name
。
现在
-AT
只是一个空串联(-y' '
与每个-x
串联),因此该选项可确保打印找到每个文本(-y
)的值
-AT
然后将与-y'[-1][power]'
串联的选项传递相同的值,但最后将在JSON树中上移1级/层,并通过-x
标签选择值
最后,所有经过的条目将使用power
选项包装回int JSON数组
更新:更简单的解决方案(只需步行一次而不是两次):
-j
PS>披露:我是bash $ <file.json jtc -w'<AT>l:<at>v[^0][name]:<at>s[-1][:]' -jr
[ "text", 10, "text2", 40 ]
bash $
-用于JSON操作的shell cli工具的创建者