shevy
shevy

Reputation: 1000

How to filter for an array, based on a glob like '*.rb'

Here is my data structure:

array = [

 ['foo.rb', 'file', '2432'],
 ['bar/', 'directory', '2048'],
 ['bla.yml', 'file', '10'],
 ['ble.rb', 'file', '2156']
]

Now I wish to find all .rb files.

My filter thus looks like this:

filter = '*.rb'

Is there a way to filter this properly on the array variable?

The result should be:

array = [
 ['foo.rb', 'file', '2432'],
 ['ble.rb', 'file', '2156']
]

If it were via Dir.glob() it would be easy, but this is an array-like datastructure and I am a bit confused how I could easily filter on it.

Upvotes: 0

Views: 321

Answers (4)

Arup Rakshit
Arup Rakshit

Reputation: 118271

You can also use the method File.extname.

array = [
          ['foo.rb', 'file', '2432'],
          ['bar/', 'directory', '2048'],
          ['bla.yml', 'file', '10'],
          ['ble.rb', 'file', '2156']
        ]

array.select { |a| File.extname(a.first) == '.rb' }
# => [["foo.rb", "file", "2432"], ["ble.rb", "file", "2156"]]

Upvotes: 0

Jordan Running
Jordan Running

Reputation: 106027

You can use File.fnmatch? to do shell-style filename globbing on any string:

files = [ [ 'foo.rb', 'file', '2432' ],
          [ 'bar/', 'directory', '2048' ],
          [ 'bla.yml', 'file', '10' ],
          [ 'ble.rb', 'file', '2156' ]
        ]

pattern = "*.rb"

files.select do |filename,|
  File.fnmatch?(pattern, filename)
end
# => [ [ 'foo.rb', 'file', '2432' ],
#      [ 'ble.rb', 'file', '2156' ] ]

Note the comma in do |filename,|. This is just syntactic sugar which discards all but the first element of the array, making the block equivalent to:

files.select do |arr|
  filename = arr[0]
  File.fnmatch?(pattern, filename)
end

Upvotes: 1

aromero
aromero

Reputation: 25761

array.select{|x| x[0].end_with?(".rb") }

Upvotes: 1

Dave Newton
Dave Newton

Reputation: 160191

>> array.find_all { |finfo| finfo[0].end_with?(".rb") }
=> [["foo.rb", "file", "2432"], ["ble.rb", "file", "2156"]]

Upvotes: 0

Related Questions