在我的控制器中,我按字母顺序传递给一组视图,如下所示:
public function index()
{
$categories = Category::orderBy('name', 'asc')->get();
return view('categories')->with('categories',$categories);
}
在我看来,我希望在与这些类别中的每个字母相对应的单独列中显示,因此在“A”列中,我将使用以A开头的所有类别,依此类推。
是否可以在视图中逐字过滤结果以实现此目的,如果是,可以如何完成?
您可以按控制器中的第一个字母对类别列表进行分组,然后将结果传递给您的视图,以下是如何操作:
控制器:
public function index() {
$categories = Category::orderBy('name', 'asc')->get();
$groups = $categories->reduce(function ($carry, $category) {
// get first letter
$first_letter = $category['name'][0];
if ( !isset($carry[$first_letter]) ) {
$carry[$first_letter] = [];
}
$carry[$first_letter][] = $category;
return $carry;
}, []);
return view('categories')->with('groups', $groups);
}
视图:
@foreach($groups as $letter => $group)
<ul>
<li>{{ $letter }}</li>
@foreach($group as $category)
<li>{{ $category['name'] }}</li>
@endforeach
</ul>
@endforeach
这是一个使用example的工作array_reduce(它与上面的Collection::reduce函数相同)
在您的视图中,而不是使用foreach
使用for
并有条件地检查每个当前项的第一个字母与其前一项的第一个字符:
<h4>{{$categories[0]->name[0]}}</h4>
@for($i = 0; $i < count($categories); $i++)
@if($i > 0 && $categories[$i]->name[0] != $categories[$i-1]->name[0])
<h4>{{$categories[$i]->name[0]}}</h4>
@endif
.....
@endfor
此解决方案中使用的另一个事实是,您可以通过该字符串中的索引访问字符串中的字符。即我们通过类别名称字符串中的索引0
访问第一个字符。
如果要仅使用指定的第一个字母从数据库加载类别:
$categories = Category::where('name', 'like', 'A%')->orderBy('name', 'asc')->get();
如果要加载所有类别然后过滤它们,请使用filter()
方法:
@foreach ('ABCDEFGHIJKLMNOPQRSTUVWXYZ' as $letter)
@foreach ($categories->filter(function($i) use($letter) { return starts_with($i->name, $letter); }) as $category)
{{ $category->name }}
@endforeach
@endforeach