Laravel:属性 上的过滤器集合,有一个转折
Laravel: Filter collection on property, with a twist
我正在寻找一个优雅的(一年后可以理解的)解决方案来解决集合过滤挑战。
我正在查询日志数据库并获得以下某种数据结构
| refId | isDeleted | loggedDate |
|---------|-------------|---------------------|
| 1 | 0 | 2018-02-23 21:39:05 |
| 2 | 0 | 2018-02-23 21:39:05 |
| 3 | 0 | 2018-02-23 21:39:05 |
| 4 | 0 | 2018-02-23 21:39:05 |
| 2 | 1 | 2018-02-23 21:49:05 |
| 5 | 0 | 2018-02-23 21:49:05 |
| 6 | 1 | 2018-02-23 21:49:05 |
我的 objective 是过滤掉同时具有 isDeleted=0
&& isDeleted=1
的条目,只留下 isDeleted=0
或 [=14] 的条目=].在这个例子中,我最终应该得到 1、3、4、5 和 6 的数据集。
谢谢。
PS。该集合最多可容纳 1000 个条目,如果您要问...
也许您可以 group by refId
和 isDeleted
并过滤只有一个条目的组。
$refIds = $collection->groupBy(['refId', 'isDeleted'])->filter(function($refGroup) {
return count($refGroup) === 1;
});
我目前无法对此进行测试以验证它是否有效,我只是试图根据 Laravel 文档在 SQL 中想出一个近似方法。
虽然结果仍会被分组,因此它可能不是那么方便,具体取决于您的使用方式。
感谢 Don't Panic 建议,我想出了以下链。
$collection->groupBy('refId')
->filter( function($refGroup) {
if ( $refGroup->count() > 1 ) {
# 0 + 1
$length = $refGroup->count();
$sum = $refGroup->reduce(function($carry, $item){
return $carry + $item->isDeleted;
});
# all sum=0 refIds are OK (no deletions)
if ( $sum == 0 ) {
return $refGroup;
} else {
# all sum=1 are good if the length=1 (deleted once)
if ( $length == $sum ) {
return $refGroup;
} else {
# sum=1 and length more than 1? manipulated and deleted => ignore
return false;
}
}
} else {
return $refGroup;
}
})
->flatten(1)
->unique('refId');
第一次测试没问题。不过,需要使用不同的数据集对其进行测试。
我正在寻找一个优雅的(一年后可以理解的)解决方案来解决集合过滤挑战。 我正在查询日志数据库并获得以下某种数据结构
| refId | isDeleted | loggedDate |
|---------|-------------|---------------------|
| 1 | 0 | 2018-02-23 21:39:05 |
| 2 | 0 | 2018-02-23 21:39:05 |
| 3 | 0 | 2018-02-23 21:39:05 |
| 4 | 0 | 2018-02-23 21:39:05 |
| 2 | 1 | 2018-02-23 21:49:05 |
| 5 | 0 | 2018-02-23 21:49:05 |
| 6 | 1 | 2018-02-23 21:49:05 |
我的 objective 是过滤掉同时具有 isDeleted=0
&& isDeleted=1
的条目,只留下 isDeleted=0
或 [=14] 的条目=].在这个例子中,我最终应该得到 1、3、4、5 和 6 的数据集。
谢谢。
PS。该集合最多可容纳 1000 个条目,如果您要问...
也许您可以 group by refId
和 isDeleted
并过滤只有一个条目的组。
$refIds = $collection->groupBy(['refId', 'isDeleted'])->filter(function($refGroup) {
return count($refGroup) === 1;
});
我目前无法对此进行测试以验证它是否有效,我只是试图根据 Laravel 文档在 SQL 中想出一个近似方法。
虽然结果仍会被分组,因此它可能不是那么方便,具体取决于您的使用方式。
感谢 Don't Panic 建议,我想出了以下链。
$collection->groupBy('refId')
->filter( function($refGroup) {
if ( $refGroup->count() > 1 ) {
# 0 + 1
$length = $refGroup->count();
$sum = $refGroup->reduce(function($carry, $item){
return $carry + $item->isDeleted;
});
# all sum=0 refIds are OK (no deletions)
if ( $sum == 0 ) {
return $refGroup;
} else {
# all sum=1 are good if the length=1 (deleted once)
if ( $length == $sum ) {
return $refGroup;
} else {
# sum=1 and length more than 1? manipulated and deleted => ignore
return false;
}
}
} else {
return $refGroup;
}
})
->flatten(1)
->unique('refId');
第一次测试没问题。不过,需要使用不同的数据集对其进行测试。