Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Question about arrays, .include and .each

Hello to everyone who decides to read over this, and specially to those who can help :D

I've become stumped over an issue that I'm having while making a script, that I just can't seem to get past.
What I'm attempting to do is to check whether an array, let's call it array a contains all elements in array b.  Sounds simple enough, right?

Code:
a = [1,2,3,4,5]
b = [1,3]

So, I attempted to do the logical thing, here, not sure if it would work, but it didnt hurt to try, right?

Code:
if a.include?(b)
  p "yay"
end

Of course, that didn't work, the expression would always evaluate false.
Now, the easiest thing to do here is to check each item, as so

Code:
if a.include?(b[0]) and a.include?(b[1]
  p "yay"
end

However, in my script, array b may change size, therefore the code above wouldn't work anymore
The next thing I thought of doing would be a loop ...

Code:
c = true
for i in 0...b.size
  c = a.include?(b[i]) ? c : false
end
p "yay" if c

And I believe that would work; however, I was thinking if it was possible to use the .each command here.
So I tried the following code

Code:
if b.each {|x|a.include?(x)}
  p "yay"
end

However, it didn't work, so my question is ... Is there some way to use the .each command for my problem, or am I just overcomplicating things, and should stay with the loop?
 
i encountered a similar problem a while back and this is how i overcame it:

i created a method:
Code:
def are_all_present?(array1, array2)
   values = []
   for element in array1
      if array2.include?(element)
         values.push(true)
      else
         values.push(false)
      end
   end
   return false if values.include?(false)
   return true
end

In the above code, array1 is the small array to be checked and array2 is the big array. you create a new local array in the method (values) and loop through each element of array1 to see if it is in array1, pushing true/false into values as appropriate.
Now after all that if a single false is in array1, it returns false (ie it doesn't contain all the items), or it returns true if all are true.

now make a method call, in your case it would read:

are_all_present?(b, a)
  p "yay"
end

hope this helps
 

khmp

Sponsor

The reason a.include?(b) didn't work is because it was looking for an array inside an array. The comparison check went like this:

Code:
a.each do |part|
  return true if part == [1, 3]
end
return false

You're over thinking things guys. You can logically "and" the arrays in one line. Skip the for loops.

Code:
a = [5, 3, 6, 1]
b = [1, 7, 2]

c = a & b
unless c.empty?
  # Code would go here that involves an array with more than zero elements in it.
else
  # Empty Array
end
 
@TywinLannister2: Thanks, but khmp is right ... we are overcomplicating things. xD

@khmp: You are kidding me ... xD
All I had to do was use & to create a new array with the elements present in both a, and b? ...
Now I feel dumb :P

I also ended up thinking about this while I was taking a shower, and it appears that

Code:
c = true
b.each {|x| c = a.include?(x) ? c : false}
p "yay" if c

also works, but your approach is far simpler. xD

Thanks. ^_^
 

e

Sponsor

You could also just do :

Code:
if (a & b).empty?
  # do code
end

Unless you want to keep the intersection results, that is. But yeah, pretty much what khmp said. :thumb:
 

e

Sponsor

If you're using this, though, you should probably do :

Code:
b.uniq.each { |x| c = a.include(x) ? c : false }

Just so you don't waste time if you get a huge array with multiple similar values.
 

khmp

Sponsor

etheon":1h8xmlf5 said:
If you're using this, though, you should probably do :

Code:
b.uniq.each { |x| c = a.include(x) ? c : false }

Just so you don't waste time if you get a huge array with multiple similar values.

I love these threads <3. They always bring new ways of looking at the same problem.
 
@etheon: Wow, thanks! I didn't know there was a .uniq feature.  I was only using it for a array size three and smaller, but yeah, that features would help a lot with bigger arrays. :D

@khmp: All roads end in Rome, as they say. xP
 

loam

Member

Someone needs to correct me if I'm wrong.

Code:
a = [5, 3, 6, 1]
b = [1, 7, 2]

c = a & b
unless c.empty?
  # Code would go here that involves an array with more than zero elements in it.
else
  # Empty Array
end

In this case, c = [1], and because c isn't empty it's gonna run the array code. The original intent, however, was to check if a contained all of b.

What I'm attempting to do is to check whether an array, let's call it array a contains all elements in array b.

Am I understanding that wrong? In the above example, a only contains 1 element of b, not all of b's elements.

If that is still a consideration, we require a different solution. A start is to change the conditional like so:

Code:
a = [whatever]
b = [another whatever]

c = a & b

if c.sort == b.sort then
  do stuff
else
  don't do stuff
end

Using & and .uniq also remove duplicates, so there would be times when this still wouldn't work, but I'm assuming that won't matter?
 

Zeriab

Sponsor

Look at the problem differently.
If a contained all of b, then all elements in b exists in a. We can also say that there will be no element in b that does not exist in a.
What if removed all elements in b that exists in a? Arrays have a set different method which is used like the regular minus.
As an example: (Notice that it is b - a and not a - b)

Code:
a = [1, 2, 3, 4, 5]
b = [1, 3]

if (b - a).empty?
  # All elements in b are in a.
else
  # There exist an element in b which does not exist in a.
end

I find this the easiest way to approach the problem.

@Loam: You still need b.uniq.sort ^^

*hugs*
- Zeriab
 

e

Sponsor

Zeriab : It's nearly the same as doing (a & b).empty?

I don't know which is fastest though, but I doubt there's much difference.

Plus, if you & them, you don't have to worry about the order you put them in :p
 

loam

Member

That's neater. And @etheon, it doesn't matter which order they go in if you - them either.

Zeriab":2m80s5tr said:
@Loam: You still need b.uniq.sort ^^

& automatically does uniq versions of the arrays, so it's already included, except for the conditional, where its non-inclusion is purposeful. It depends what exactly you are checking for. If you are checking to see if a contains all of b, then you need to make sure you are not removing duplicates.

In other words:

a = [1, 2, 3, 4]
b = [1, 2, 2]

Does a actually contain b, for what we are concerned with? Because your method and the other similar ones would say it does. That's why I was asking the OP for clarification on what they needed. If it's not a concern then your method looks cleanest imo.

Just to clarify, what I posted wouldn't work either if you need duplicates. Right now it can just tell if the array c is actually equal to b or not. You would need to change things around further. One of the .each things would really be best, I dunno...

edit: hopefully clearer now.
 

Zeriab

Sponsor

Ah yes, I did not consider duplicates
& and - are Set operations
Since a set is a collection of distinct objects I do not recommend using set operations in case duplicates matters.

In that case I would sort both arrays and then run the values of b through while checking them up against the values in a.
I am too lazy to do it if vpcdmd's problem is solved though >_>

btw.
Your solution will not give the correct result in this examples:
a = [1, 2, 2, 3, 4]
b = [1, 2, 2]

@vpcdmd:
Does duplicates matter? Or are duplicates ignored?
In the example loam gave:
In other words:

a = [1, 2, 3, 4]
b = [1, 2, 2]
Will a contain all elements of b in that case?

@etheon:
There are major difference betweens set difference and set intersection.
You see, the set intersection a & b will be: (b & a will give the same result)
http://img530.imageshack.us/img530/7126 ... ionkb9.png[/img]
While the difference b - a will be: (a - b can give something else)
http://img182.imageshack.us/img182/2382 ... ncezz1.png[/img]

I would say it's far from the same, though that is a subjective matter :P
 
Hahaha ... wow, and I thought I was overcomplicating things. xD
I actually do think that in this case - would work better than &.

And don't worry about duplicates, they don't matter for what I wanted to do.
Thanks for the interest though :D
 

khmp

Sponsor

vpcdmd":qd8g0azr said:
Hahaha ... wow, and I thought I was overcomplicating things. xD
I actually do think that in this case - would work better than &.

And don't worry about duplicates, they don't matter for what I wanted to do.
Thanks for the interest though :D

You started this. :lol:

I think once it gets to how it'll look in byte memory and the assembly instructions is when this has gone too far. Until then though, read and try to understand what they are saying.
 
lol, I know I've started it. xD
And I've read it all, and understood it all.

I only said it was going too far since it was way more than what I needed, but I guess if they want to discuss their ideas, they are more than free of doing so ;)
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top