我正在构建自定义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很常见?
答案 0 :(得分:0)
结果数据中的每个“组”看起来都包含特定年份特定公司的季度。您可以使用雄辩的方法来完成此任务,而不是遍历整个季度。我用40k条记录对此进行了测试。循环大约需要45秒,但这不到一秒钟。
flatten()
请小心使用哪种雄辩的方法。如果您使用{{1}},则该方法将在内部使用递归循环,因此它仍然很慢。