我喜欢使用jq过滤json文件:
jq . some.json
给定json包含一个对象数组:
{
"theList": [
{
"id": 1,
"name": "Horst"
},
{
"id": 2,
"name": "Fritz"
},
{
"id": 3,
"name": "Walter"
},
{
"id": 4,
"name": "Gerhart"
},
{
"id": 5,
"name": "Harmut"
}
]
}
我想过滤该列表,只显示id为2和4的元素,因此预期输出为:
{
"id": 2,
"name": "Fritz"
},
{
"id": 4,
"name": "Gerhart"
}
如何使用jq过滤json?我玩过选择和地图,但没有任何工作,例如:
$ jq '.theList[] | select(.id == 2) or select(.id == 4)' array.json
true
答案 0 :(得分:30)
来自文档:
jq '.[] | select(.id == "second")'
输入
[{"id": "first", "val": 1}, {"id": "second", "val": 2}]
输出
{"id": "second", "val": 2}
我认为你可以这样做:
jq '.theList[] | select(.id == 2 or .id == 4)' array.json
答案 1 :(得分:8)
您可以在select
中使用map
。
.theList | map(select(.id == (2, 4)))
或更紧凑:
[ .theList[] | select(.id == (2, 4)) ]
虽然以这种方式编写的方式效率有点低,因为对于每个被比较的值,表达式都是重复的。它会以这种方式更高效,更可读:
[ .theList[] | select(any(2, 4; . == .id)) ]
答案 2 :(得分:3)
在这里使用select(.id == (2, 4))
通常效率低下(见下文)。
如果你的jq有IN/1
,那么它可以用来实现更有效的解决方案:
.theList[] | select( .id | IN(2,3))
如果您的jq没有IN/1
,那么您可以按如下方式定义:
def IN(s): first(select(s == .)) // false;
<强>效率强>
查看效率低下的一种方法是使用debug
。例如,以下表达式导致对debug
的10次调用,而实际上只需要9次检查是否相等:
.theList[] | select( (.id == (2,3)) | debug )
["DEBUG:",false]
["DEBUG:",false]
["DEBUG:",true]
{
"id": 2,
"name": "Fritz"
}
["DEBUG:",false]
["DEBUG:",false]
["DEBUG:",true]
{
"id": 3,
"name": "Walter"
}
["DEBUG:",false]
["DEBUG:",false]
["DEBUG:",false]
["DEBUG:",false]
<强>索引/ 1 强>
原则上,使用index/1
应该是有效的,但在撰写本文时(2017年10月),其实现虽然速度很快(用C语言编写),但效率很低。
答案 3 :(得分:0)
以下是使用indices的解决方案:
import org.apache.spark.sql.functions.{col}
import org.apache.spark.sql.types._
res.withColumn("c3", (col("c1")/col("c2"))
.cast(DecimalType(4,4)))
.orderBy(col("c3").desc).show()