MichaelR
MichaelR

Reputation: 999

Check if partial value is inside array

I have this array :

>> arr = [["a",1,"b"],["a",2,"b"],["b",3,"d"],["t",6,"a"]]

I want to check if ["a",1] exists inside the arr while ignoring the 3rd value of the arr items.

Is there a better way then first removing the 3rd value from each item in arr:

>> new_arr = [["a",1],["a",2],["b",3],["t",6]]

and then doing

>> new_arr.include? ["a",1]
true

Something like:

arr.include? ["a",1,/*/]  #the 3rd value can be anything

Thanks.

Upvotes: 1

Views: 81

Answers (3)

Cary Swoveland
Cary Swoveland

Reputation: 110685

Another way:

def values_there?(arr, val)
  arr.transpose[0,val.size].transpose.include? val
end

values_there?(arr, ["a", 2]) #=> true
values_there?(arr, [3, "d"]) #=> false

Upvotes: 0

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230346

Here's a more complicated version of @Arup's answer (it handles arbitrary lengths, though)

def match_head(*head)
  ->(full_array) {
    head.each_with_index do |head_elem, idx|
      return false if full_array[idx] != head_elem
    end

    true
  }
end

ary = [["a",1,"b"],["a",2,"b"],["b",3,"d"],["t",6,"a"]]
ary.any?(&match_head('a')) # => true
ary.any?(&match_head('c')) # => false
ary.any?(&match_head('a', 1)) # => true
ary.any?(&match_head('a', 1, 'b')) # => true
ary.any?(&match_head('a', 1, 'f')) # => false

Upvotes: 2

Arup Rakshit
Arup Rakshit

Reputation: 118271

You can try the below :

arr = [["a",1,"b"],["a",2,"b"],["b",3,"d"],["t",6,"a"]]
arr.any? { |v1, v2, *| [v1, v2] == ["a", 1] }
# => true
arr.any? { |v1, v2, *| [v1, v2] == ["a", 4] }
# => false

wrap the logic inside a method :

def check_subarray(ary, sub_ary)
  ary.any? { |e1, e2, *| [e1, e2] == sub_ary }
end

arr = [["a",1,"b"],["a",2,"b"],["b",3,"d"],["t",6,"a"]]
check_subarray(arr, ["a", 1]) # => true

Upvotes: 4

Related Questions