A way to .count only the first 3 digits in each array slot?

Hello,

Is there a way to use .count to only look at the first 3 digits in each array slot?

For example, if I had an array, array = [234, 928234, 234932] i need to count how many of the numbers in the array have the first 3 numbers the same as 234. If I use array.count(“234”) it will show that array[0…2] have 234 in them but I only want to look at the first 3 numbers. The result should show that only array[0] and array[2] have 234 as the first 3 digits.

is there something you can add to array.count{ } to make it only look at the first 3 digits in each array slot?

Thanks

# for numbers that match
array = [234, 928234, 234932]
array.select { |num| "#{num}" =~ /\A234.*/ }
# => [234, 234932]


# for indexes that match
array.each_with_index.
  reduce([]) { |arr, (num, index)|
    arr << index if "#{num}" =~ /\A234/
    arr
  }
# => [0, 2]
2 Likes

I like to use /\A234/ === num.to_s instead, since === with the regexp on the left side will return true or false instead of the index of the match. (Also, no need to match more with .* in this case)

For the index part, I find this easier to reason about:

array.each_with_object([]).with_index do |(num, ary), idx|
  ary << idx if /\A234/ === num.to_s
end
# => [0, 2]
2 Likes

Thanks! also where is the best place to learn about all of those things. I am really new to ruby and I don’t understand what the slashes are for inside the curly brackets. Maybe you guys have a suggested book or website that helped you learn ruby?

Thanks again for the help!

Thanks!

now what if I wanted to make the number it searches for variable. For example if I always wanted to search for the number in array[0] in all other slots.

so say the next input is… array = [432, 124232, 13421, 4329654]

how do I make that search variable? I noticed array.select { |num| “#{num}” =~ /\array[0].*/ } doesn’t work, but I know nothing about this call out.

Those slashes are what’s called Regex. To use a variable in regex you do the same thing as you would a string by adding string interpolation so "#{something}" and /#{something}/ will put what ever the variable something is in it.

If you’re going to do that you may as well wrap it in a function with a parameter for the variable.

Re-implementing the answers with @Ohm’s suggestions, your feature request, and added function names the code will look like this.

the_array = [234, 928234, 234932]

def find_numbers_with(partial, array)
  array.select { |num| /\A#{partial}/ === num.to_s }
end

find_numbers_with("234", the_array)
# => [234, 234932]

def find_indexes_with(partial, array)
  array.each_with_object([]).with_index { |(num, ary), idx|
    ary << idx if /\A#{partial}/ === num.to_s
  }
end

find_indexes_with("234", the_array)
# => [0, 2]

In Regex the \A means that what follows it has to be at the beginning of the string.

To learn more about working with arrays you need to look into enumeration in Ruby which is defined in Enumerable and Enumerator. But for the best learning experience I suggest learning it through https://rubymonk.com/

Hey @Ohm , you have a mismatch between {} and do end in your example.

1 Like

Write a method that returns an Enumerator of digits of n in the big-endian order, without converting n to a string:

def digits(n)
  result = []
  begin
    result << n % 10
    n /= 10
  end until n <= 0
  result.reverse_each
end

Now you can use it like this:

[234, 928234, 234932].count { |n| digits(n).take(3) == [2, 3, 4] }

Note that this solution and the solutions above only work for positive integers. I assume that’s OK as the question does not specify what to do with the negative integers.

1 Like