SitePoint Sponsor

User Tag List

Results 1 to 8 of 8
  1. #1
    SitePoint Guru downtroden's Avatar
    Join Date
    Dec 2004
    Location
    illinois
    Posts
    971
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    testing all values in an array against single integer

    Right now here's what I have
    Code Ruby:
    <% @month_event_dates.each do |d| -%>
      <% if counter == d -%>
         <%= link_to counter, { :controller => 'calendar', :action => 'list_date' } -%>
      <% else -%>
         <%= counter -%>
      <% end -%>
    <% end -%>

    So as the counter counts up, it looks to see if each array value is equal to the current value of counter. Right now there are three values to test against, this could go up or could go down and since it's outputting counter three times, when the number of array elements went up, that would be bad.

    So is there a way to say

    if x == any element in array "do this" else "do that"

    Any help is appreciated! Thanks.
    your brain reacts in the same way whether you are
    looking at something or thinking about it...

  2. #2
    SitePoint Wizard
    Join Date
    Mar 2001
    Posts
    3,537
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code Ruby:
    arr = [10, 20, 30, 40]
    x = 30
     
    arr.each do |item|
        if item == x 
            puts "world" 
        else
            puts "hello"
        end 
    end 
     
    --output:--
    hello
    hello
    world
    hello
    But that's what you already have, so it's not clear what the problem is. The size of the array is never used in the code. It doesn't matter whether there is one element in the array or 10,000:


    Code Ruby:
    def func(arr, x)
     
        arr.each do |item|
            if item == x
                puts "world"
            else
                puts "hello"
            end
        end
    end
     
    arr1 = [10]
    x = 30
     
    func(arr1, x)
    puts
     
    arr1.push(30, 2, 1, 3)
    func(arr1, x)
    puts
     
    arr1.push(30,30,30,30,30,30)
    func(arr1, x)
     
     
    --output:--
    hello
     
    hello
    world
    hello
    hello
    hello
     
    hello
    world
    hello
    hello
    hello
    world
    world
    world
    world
    world
    world

    Ahh, I think I deciphered what you want. You want the test to be:

    --if number in the array, then do something
    --else do another thing

    One way would be to use a break statement in a loop:
    Code Ruby:
    arr = [20, 30, 30, 30, 40] 
    x = 30
    found = false 
     
    for item in arr: 
        if item == x
            found = true
            break   
        end
    end
     
    if found
        puts "Yes sireee!"
    else
        puts "Nope"
    end
    But since Ruby has a method for everything, all you have to do is look in the Array class in your favorite Ruby documentation, say by typing:

    $ ri Array

    and read down the list of methods. You'll see the method include?. So, you can do this:

    Code Ruby:
    arr = [20, 30, 30, 30, 40]
    x = 30
     
    if arr.include?(x)
        puts "Yes siree"
    else
        puts "Nope"
    end
    Last edited by 7stud; Sep 9, 2007 at 06:45.

  3. #3
    ☆★☆★ silver trophy vgarcia's Avatar
    Join Date
    Jan 2002
    Location
    in transition
    Posts
    21,235
    Mentioned
    1 Post(s)
    Tagged
    1 Thread(s)
    Put this method in your controller's associated helper:
    Code ruby:
    #"haystack" is an array of values to check against
    #"needle" is the desired value
    def search_stack(haystack, needle, &block)
      if haystack.include? needle
        yield needle
      else
        needle
      end
    end
    In your view:
    Code ruby:
    <&#37;= search_stack(@month.event_dates, counter) { |counter| link_to counter, :controller => 'calendar', :action => 'list_date' } %>
    If the value of counter isn't found in the list of dates, it will just output the value of counter. If the value of counter is found, it will output whatever you put in the block (in this case, link_to).

  4. #4
    SitePoint Guru downtroden's Avatar
    Join Date
    Dec 2004
    Location
    illinois
    Posts
    971
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    wow! thanks garcia... now I just need to break it down and understand whats going on.

    Once again, thank you for the help!
    your brain reacts in the same way whether you are
    looking at something or thinking about it...

  5. #5
    SitePoint Wizard
    Join Date
    Mar 2001
    Posts
    3,537
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    just need to break it down and understand whats going on
    If you define a method like this:

    Code Ruby:
    def do_something(num1, num2, &func) 
         ...
         ...
    end

    where the last parameter has a '&' in front of it, when you call the method like this:

    Code Ruby:
    do_something(1, 2) {|x| puts x}

    the block to the right of the method call is converted to a *Proc object*(more on what that means below). Then the Proc object is assigned to the parameter variable 'func' in do_something(). It's like doing this:

    Code Ruby:
    do_something(1, 2, {|x| puts x} )
    (That is supposed to look like the block is listed as the third argument in the method call.)

    So, what is a Proc object good for? You can execute the block using the Proc object's call() method:

    Code Ruby:
    def do_something(num1, num2, &func) 
         func.call(the args the func requires go here)
         ...
    end

    Here is a complete example:

    Code Ruby:
    def do_something(num1, num2, &func)
        puts num1, num2
        func.call("red")
    end
     
     
    do_something(1, 2) {|x| puts x} 
     
    --output:--
    1
    2
    red
    Note that the statement func.call("red") sends one argument to the block, and the block is defined to accept one argument:

    Code Ruby:
    {|x| puts x}

    The statement:

    Code Ruby:
    func.call("red")
    is similar to calling a regular method like this:

    Code Ruby:
    some_func("red")

  6. #6
    SitePoint Addict
    Join Date
    Jan 2006
    Posts
    268
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    is "yield needle" like calling "func.call(needle)" ??
    If you give someone a program,
    you will frustrate them for a day;
    if you teach them how to program,
    you will frustrate them for a lifetime.

  7. #7
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes.

    Free hint.

    It's like func[needle] too. Handy for things like

    Code ruby:
    # can be indexed like an array of all even numbers
    evens = lambda{|x| 2*x}
    # evens = [0,2,4,...]
     
    evens[3] #=> 6

  8. #8
    SitePoint Addict
    Join Date
    Mar 2004
    Location
    Grand Junction, CO
    Posts
    292
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    vinnie's suggestion is a great example of the power of blocks. However I would use

    Code:
    link_to_if (counter == d), counter, { :controller => 'calendar', :action => 'list_date' }
    because it is idiomatic Rails.

    Here's the documentation

    Also I'm not sure what exactly the condition is supposed to be (OP's code and commentary seemed to clash), but you just use that as the first arg to link_to_if. So you could do

    Code:
    link_to_if @month_event_dates.include?(counter), counter, { :controller => 'calendar', :action => 'list_date' }


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •