Filter collection using like and wildcard

Viewed 4273

I need to get all files which starts with desired letter, I'm trying to use a ->where filter adding 'like' as operator but wildcards doesn't work.

        $files = File::files(storage_path($id_files));
        $files = collect($files);
        $files->transform(function ($item, $key){
            $item->public_filename = $item->getFilename();
            return $item;
        });

This is our target data, I need to create a public_filename field to apply filters to. Our files (dd($files)):

   Collection {#503 ▼
  #items: array:3 [▼
    0 => SplFileInfo {#525 ▼
      -relativePath: ""
      -relativePathname: "atxt.txt"
      path: "/home/vagrant/Code/project/storage/app/uploads/general"
      filename: "atxt.txt"
      basename: "atxt.txt"
      pathname: "/home/vagrant/Code/project/storage/app/uploads/general/atxt.txt"
      extension: "txt"
      realPath: "/home/vagrant/Code/project/storage/app/uploads/general/atxt.txt"
      aTime: 2017-09-29 09:51:17
      mTime: 2017-09-27 14:39:11
      cTime: 2017-09-27 14:39:11
      inode: 32833
      size: 3
      perms: 0100777
      owner: 1000
      group: 1000
      type: "file"
      writable: true
      readable: true
      executable: true
      file: true
      dir: false
      link: false
    }
    1 => SplFileInfo {#524 ▼
      -relativePath: ""
      -relativePathname: "batxt.txt"
      path: "/home/vagrant/Code/project/storage/app/uploads/general"
      filename: "batxt.txt"
      basename: "batxt.txt"
      pathname: "/home/vagrant/Code/project/storage/app/uploads/general/batxt.txt"
      extension: "txt"
      realPath: "/home/vagrant/Code/project/storage/app/uploads/general/batxt.txt"
      aTime: 2017-09-29 09:51:31
      mTime: 2017-09-27 14:39:11
      cTime: 2017-09-27 14:39:11
      inode: 32834
      size: 3
      perms: 0100777
      owner: 1000
      group: 1000
      type: "file"
      writable: true
      readable: true
      executable: true
      file: true
      dir: false
      link: false
    }
    2 => SplFileInfo {#526 ▼
      -relativePath: ""
      -relativePathname: "txt.txt"
      path: "/home/vagrant/Code/project/storage/app/uploads/general"
      filename: "txt.txt"
      basename: "txt.txt"
      pathname: "/home/vagrant/Code/project/storage/app/uploads/general/txt.txt"
      extension: "txt"
      realPath: "/home/vagrant/Code/project/storage/app/uploads/general/txt.txt"
      aTime: 2017-09-27 14:39:11
      mTime: 2017-09-27 14:39:11
      cTime: 2017-09-27 14:39:11
      inode: 5438
      size: 3
      perms: 0100777
      owner: 1000
      group: 1000
      type: "file"
      writable: true
      readable: true
      executable: true
      file: true
      dir: false
      link: false
    }
  ]
}

What I'm trying:

dd($files->where('public_filename','like','t%')); // 0 results

dd($files->where('public_filename','like','txt.txt')); //If I ommit wildcard and look for full name it retrieves correct file

So our target is:

dd($files->where('public_filename','like','t%')); // 1 result

Any idea? Could we use wildcards to filter a collection by using a like operator? Thank you guys!

1 Answers

Indeed there is no where like in laravel collection but because the where function also employs filter in the background, as said in the comment you can build your filter based on your need.

An example is the following that filter returned users whose name starts with T

    $collect = User::all()->filter(function($user){
        return starts_with($user->name, 'T');
    });

Laravel also has several functions that can help manipulate and use strings such as ends_with(), str_contains() etc. Other php string manipulation functions are there to aid you.

PS Generally you'll want to commit your db to do the filtering when fetching the data (at least for the example I just gave)

Related