【问题标题】:How to display records in view based on their first letter?如何根据第一个字母在视图中显示记录?
【发布时间】:2018-06-06 21:01:40
【问题描述】:

在我的控制器中,我将一堆按字母顺序排列的类别传递给视图,如下所示:

public function index()
    {
        $categories = Category::orderBy('name', 'asc')->get();

        return view('categories')->with('categories',$categories);
    }

在我看来,我想在单独的列中显示与这些类别中的每一个字母相对应的字母,因此在“A”列中,我将拥有以 A 开头的所有类别,依​​此类推。

是否可以按字母过滤视图中的结果以实现此目的,如果可以,如何实现?

【问题讨论】:

    标签: laravel model-view-controller eloquent laravel-blade


    【解决方案1】:

    您可以在控制器中按首字母对类别列表进行分组,然后将结果传递给您的视图,方法如下:

    控制器:

    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
    

    这是一个使用array_reduce 的工作example(与上面的Collection::reduce 函数相同)

    【讨论】:

      【解决方案2】:

      在您看来,不要使用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 访问第一个字符。

      【讨论】:

        【解决方案3】:

        如果您只想从数据库中加载具有指定首字母的类别:

        $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
        

        【讨论】:

        • 不,我想在视图中过滤它们。如果我像这样加载它们,它们将不会按字母顺序排列。而且我将需要控制器中的大量变量。所以我只想在它们已经按字母顺序排列时(就像现在一样)根据它们的第一个字母在视图中过滤它们
        • @incense_stick 我已经用完整的解决方案更新了我的答案,您可以在视图中使用它。
        • 第一个解决方案有效,但第二个无效。否则,非常感谢!
        • 我收到 (2/2) ErrorException 为 foreach() 提供的参数无效
        • 我已在 3 分钟前更新了答案,请检查。如果你仍然得到错误,请告诉我你得到它的那一行。
        猜你喜欢
        • 1970-01-01
        • 2012-07-15
        • 2018-02-23
        • 1970-01-01
        • 1970-01-01
        • 2017-11-10
        • 1970-01-01
        • 2014-03-01
        • 2010-09-16
        相关资源
        最近更新 更多