Laravel集合按另一个集合中的值过滤一个集合

时间:2019-04-30 22:51:32

标签: php laravel

我正在构建自定义Collection类,但是在过滤数据时遇到了一些问题。

我有一个财务数据集合($ collection),看起来像这样:

App\CustomCollection {
    #items: array [
        0 => {
            +"financials": [
                0 => {
                    +"data_tag": {
                        +"tag": "revenue"
                    }
                    +"value": 1200
                }
            ]
            +"fundamental": {
                +"fiscal_year": 2018
                +"fiscal_period": "FY"
                +"start_date": "2018-01-01"
                +"end_date": "2018-12-31"
            }
            +"company": {#336
                +"id": "com_TEST1"
            }
        }
        1 => {
            +"financials": [
                0 => {
                    +"data_tag": {
                        +"tag": "revenue"
                    }
                    +"value": 300
                }
            ]
            +"fundamental": {
                +"fiscal_year": 2018
                +"fiscal_period": "Q1"
                +"end_date": "2018-03-31"
            }
            +"company": {#336
                +"name": "Test Company Inc"
            }
        }
        2 => {
            +"financials": [
                0 => {
                    +"data_tag": {
                        +"tag": "revenue"
                    }
                    +"value": 300
                }
            ]
            +"fundamental": {
                +"fiscal_year": 2018
                +"fiscal_period": "Q2"
                +"end_date": "2018-06-30"
            }
            +"company": {#336
                +"name": "Test Company Inc"
            }
        }

        ... etc to Q4
    ]
}

我可以通过以下方式成功返回我的会计年度:

$fiscalYears = $collection->where('fundamental.fiscal_period', 'FY');

返回:

App\CustomCollection {
    #items: array [
        0 => {
            +"financials": [
                0 => {
                    +"data_tag": {
                        +"tag": "revenue"
                    }
                    +"value": 1200
                }
            ]
            +"fundamental": {
                +"fiscal_year": 2018
                +"fiscal_period": "FY"
                +"start_date": "2018-01-01"
                +"end_date": "2018-12-31"
            }
            +"company": {#336
                +"id": "com_TEST1"
            }
        }
    ]
}

我还可以通过以下方式返回宿舍:

$fiscalYears = $collection->where('fundamental.fiscal_period', '!=', 'FY');

App\CustomCollection {
    #items: array [
        0 => {
            +"financials": [
                0 => {
                    +"data_tag": {
                        +"tag": "revenue"
                    }
                    +"value": 300
                }
            ]
            +"fundamental": {
                +"fiscal_year": 2018
                +"fiscal_period": "Q1"
                +"end_date": "2018-03-31"
            }
            +"company": {#336
                +"name": "Test Company Inc"
            }
        }
        1 => {
            +"financials": [
                0 => {
                    +"data_tag": {
                        +"tag": "revenue"
                    }
                    +"value": 300
                }
            ]
            +"fundamental": {
                +"fiscal_year": 2018
                +"fiscal_period": "Q2"
                +"end_date": "2018-06-30"
            }
            +"company": {#336
                +"name": "Test Company Inc"
            }
        }

        ... etc to Q4
    ]
}

这里一切都很好,并且运行良好,但是现在我要完成的工作是只返回与$ fiscalYears中的特定值匹配的季度。

这是我现在正在使用的:

public function quartersByFiscalYears($fiscalYears)
    {
        $quarters =  [];
        foreach ($fiscalYears as $fiscalYear) {
            $quarters[] = $this->quarters()->where('company', $fiscalYear->company)
                ->where('fundamental.end_date', '>=', $fiscalYear->fundamental->start_date)
                ->where('fundamental.end_date', '<', $fiscalYear->fundamental->end_date)
                ->values('financials');
        }

        return $quarters;
    }

上面代码中最重要的部分是,它仅返回$ quarter end_date> = $ fiscalYear起始日期和$ quarter end_date <$ fiscalYear终止日期的季度。

这有效,但是它是我收藏中最慢的“过滤器”。尽管我不确定,但我有种感觉,我正在考虑所有错误。每次$ fiscalYears迭代时,遍历整个集合似乎是一个坏主意。可以以更快/更有效的方式完成此操作吗?还是在这种情况下foreach很常见?

1 个答案:

答案 0 :(得分:0)

结果数据中的每个“组”看起来都包含特定年份特定公司的季度。您可以使用雄辩的方法来完成此任务,而不是遍历整个季度。我用40k条记录对此进行了测试。循环大约需要45秒,但这不到一秒钟。

flatten()

请小心使用哪种雄辩的方法。如果您使用{{1}},则该方法将在内部使用递归循环,因此它仍然很慢。