有这样的输入:
[
{
"foo": "aaa",
"bar": 111
},
{
"foo": "bbb",
"bar": 111
},
{
"foo": "ccc",
"bar": 222
},
{
"foo": "aaa",
"bar": 333
},
{
"foo": "ddd",
"bar": 444
}
]
我想选择“foo”键等于“aaa”或“bbb”的所有对象。所以解决方案很明显:
.[] | select ( .foo=="aaa" or .foo=="bbb" )
(https://jqplay.org/s/x7FGo1uQNW)
但我想增强它并将 x=y or x=z
替换为 sql'ish 样式的 x in (y,z)
。我被卡住了,这是很自然的尝试:
.[] | select ( .foo in (["aaa", "bbb"]) )
导致错误:
<块引用>jq: 错误:语法错误,意外的 IDENT,期待 ';'或 ')'(Unix shell 引用问题?)在第 1 行:
我也试过这个:
.[] | select ( .foo | in (["aaa", "bbb"]) )
但也不是很好...
<块引用>jq: error (at :21): 无法检查数组是否有字符串键
这甚至可能吗?
答案 0 :(得分:2)
嗯,我设法做到了:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".versionrecycler.VersionRecycler">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/versions_rv"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:listitem="@layout/row_versions_rv"/>
</androidx.constraintlayout.widget.ConstraintLayout>
https://jqplay.org/s/g7AyRgARdU
根据这个答案:
https://stackoverflow.com/a/46470951/2244766
在 1.5 以上的版本中,有一个新的 .[] | select(.foo as $tmpvar | ["aaa", "bbb"] | index ($tmpvar ) )
运算符,使生活更轻松:
IN
答案 1 :(得分:0)
SQL 风格的运算符作为一种直接的选择机制对我来说效果不佳;我相信它们有一个非常具体的用例,它们是独一无二的,并且对于它们(充其量)笨重的任何其他东西。至少这是我的经验。而且我也没有真正弄清楚那个特定的用例是什么。
以所有这些为背景,我的建议是使用简单的正则表达式测试:
map(select(.foo | test("aaa|bbb")))
给定示例 JSON:
<~> $ jq . /tmp/so4229.json
[
{
"foo": "aaa",
"bar": 111
},
{
"foo": "bbb",
"bar": 111
},
{
"foo": "ccc",
"bar": 222
},
{
"foo": "aaa",
"bar": 333
},
{
"foo": "ddd",
"bar": 444
}
]
上述过滤器将导致:
<~> $ jq 'map(select(.foo | test("aaa|bbb")))' /tmp/so4229.json
[
{
"foo": "aaa",
"bar": 111
},
{
"foo": "bbb",
"bar": 111
},
{
"foo": "aaa",
"bar": 333
}
]
如果您需要根据 JSON 中的其他数据生成正则表达式,您也可以这样做:
. as $data | map(select(.bar==111) | .foo) | join("|") as $regex | . = $data | map(select(.foo | test($regex)))
这将导致:
<~> $ jq '. as $data | map(select(.bar==111) | .foo) | join("|") as $regex | . = $data | map(select(.foo | test($regex)))' /tmp/so4229.json
[
{
"foo": "aaa",
"bar": 111
},
{
"foo": "bbb",
"bar": 111
},
{
"foo": "aaa",
"bar": 333
}
]
可能有更好的方法来运行 JSON 两次(一次获取正则表达式值,一次使用它)。