我已经坚持了好几天。我有一堆需要迭代的“规则”,与使用一堆数据库调用相比,使用集合要有意义得多。问题是我似乎无法获得我见过的任何解决方案。
下面是我尝试搜索的“规则”的示例。 tagId是我要寻找的结果。我们有一组标签,在groupRules和tagRules上都有一个AND或OR运算符。
本质上,在下面的列表中id:17会显示如下内容:
(225存在且235存在)或(232存在且231存在)
我一生都无法解决如何查询除每个数组的第一级以外的任何内容。
下面的功能可以正常工作,但是当我尝试深入了解tagRules甚至groupRules时,它告诉我无法找到关键的groupRules。
$tagCollection = collect($tmp)
->recursive()
->where('tagType','!=',null);
[
{
"id": 17,
"tagType": "CombinateTag",
"name": "test1",
"groupOperator": "OR",
"groupRules": [
{
"tagOperator": "AND",
"tagRules": [
{
"tagId": 225,
"hasTag": 1
},
{
"tagId": 235,
"hasTag": 1
}
]
},
{
"tagOperator": "AND",
"tagRules": [
{
"tagId": 232,
"hasTag": 0
},
{
"tagId": 231,
"hasTag": 0
}
]
}
]
},
{
"id": 18,
"tagType": "Composite",
"name": "test1a",
"groupOperator": "OR",
"groupRules": [
{
"tagOperator": "AND",
"tagRules": [
{
"tagId": 225,
"hasTag": 1
},
{
"tagId": 235,
"hasTag": 1
}
]
},
{
"tagOperator": "AND",
"tagRules": [
{
"tagId": 232,
"hasTag": 0
},
{
"tagId": 231,
"hasTag": 0
}
]
}
]
}
]
答案 0 :(得分:0)
这是一个好人!我花了一段时间,但我想我明白了。
希望我了解您想要什么,如果没有,这可能会帮助您。这很丑陋,但是您可以理解要点。
所以我的第一步是从您的json进行收集:
$tmp = json_decode('[
{
"id": 17,
"tagType": "CombinateTag",
"name": "test1",
"groupOperator": "OR",
"groupRules": [
{
"tagOperator": "AND",
"tagRules": [
{
"tagId": 225,
"hasTag": 1
},
{
"tagId": 235,
"hasTag": 0
}
]
},
{
"tagOperator": "AND",
"tagRules": [
{
"tagId": 232,
"hasTag": 0
},
{
"tagId": 231,
"hasTag": 0
}
]
}
]
},
{
"id": 18,
"tagType": "Composite",
"name": "test1a",
"groupOperator": "AND",
"groupRules": [
{
"tagOperator": "AND",
"tagRules": [
{
"tagId": 225,
"hasTag": 1
},
{
"tagId": 235,
"hasTag": 1
}
]
},
{
"tagOperator": "AND",
"tagRules": [
{
"tagId": 232,
"hasTag": 1
},
{
"tagId": 231,
"hasTag": 1
}
]
}
]
}
]', true);
$tmp = collect($tmp)->recursiveCollect();
与此:
\Illuminate\Support\Collection::macro('recursiveCollect', function () {
return $this->map(function ($value) {
if (is_array($value)) {
return collect($value)->recursiveCollect();
}
if (is_object($value)) {
return collect($value)->recursiveCollect();
}
return $value;
});
});
然后我为您的数据创建了一个宏:
\Illuminate\Support\Collection::macro('roleFilter', function ($operator = '') {
$property = '';
if ($this->has('groupRules')) { //Check if the collection has more levels
$operator = $this['groupOperator']; //set the operator
$property = 'groupRules'; //Set the property aside
}
$res = false;
if ($property === 'groupRules') { //Check if needs more digging
$res = $this[$property]->roleFilter($operator);
} else {
if ($operator === 'OR') { //validate for OR between groupRules
$res = false;
$this->each(function ($val) use (&$res) {
$has = 0;
$val['tagRules']->each(function ($v) use (&$has) {
if ($v['hasTag'] == 1) {
$has++;
}
});
if ($val['tagOperator'] === 'OR') { //validate for OR between tagRules
$res = $res || $has > 0;
} elseif ($val['tagOperator'] === 'AND') { //validate for AND between tagRules
$res = $res || $val['tagRules']->count() == $has;
}
});
} elseif ($operator === 'AND') { //validate for AND between groupRules
$res = true;
$this->each(function ($val) use (&$res) {
$has = 0;
$val['tagRules']->each(function ($v) use (&$has) {
if ($v['hasTag'] == 1) {
$has++;
}
});
if ($val['tagOperator'] === 'OR') { //validate for OR between tagRules
$res = $res && $has > 0;
} elseif ($val['tagOperator'] === 'AND') { //validate for AND between tagRules
$res = $res && $val['tagRules']->count() == $has;
}
});
}
}
return $res;
});
您可以检查以下角色:
$alloweds = $tmp->filter(function ($value) {
return $value->roleFilter();
});