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 refIdisDeleted 并过滤只有一个条目的组。

$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');

第一次测试没问题。不过,需要使用不同的数据集对其进行测试。