Putting value in sorted array

Discussion in 'Ruby' started by Jari Williamsson, Dec 8, 2007.

  1. I have an array that's sorted from highest value to lowest. I also want
    to insert a value in sort order, but only if the value doesn't exist
    already. I ended up with a solution (writing from memory here, it was on
    another computer) that feels a bit "long" for Ruby code, going something
    like this:

    ---
    arr = [5, 3, 1]
    insert_value = 2

    arr.each_index {|v, i|
    break if v == insert_value
    if insert_value > v
    arr.insert(i, insert_value)
    break
    end
    }
    ---

    Is there a "simpler" solution?


    Best regards,

    Jari Williamsson
     
    Jari Williamsson, Dec 8, 2007
    #1
    1. Advertising

  2. Jari Williamsson

    yermej Guest

    On Dec 8, 11:48 am, Jari Williamsson
    <> wrote:
    > I have an array that's sorted from highest value to lowest. I also want
    > to insert a value in sort order, but only if the value doesn't exist
    > already. I ended up with a solution (writing from memory here, it was on
    > another computer) that feels a bit "long" for Ruby code, going something
    > like this:
    >
    > ---
    > arr = [5, 3, 1]
    > insert_value = 2
    >
    > arr.each_index {|v, i|
    > break if v == insert_value
    > if insert_value > v
    > arr.insert(i, insert_value)
    > break
    > end}
    >
    > ---
    >
    > Is there a "simpler" solution?
    >
    > Best regards,
    >
    > Jari Williamsson


    I guess it depends on how much efficiency you need. You could always
    do:

    arr = [5, 3, 1]
    insert_value = 2
    (arr << insert_value).uniq!
    arr.sort!.reverse!
     
    yermej, Dec 8, 2007
    #2
    1. Advertising

  3. yermej wrote:
    > On Dec 8, 11:48 am, Jari Williamsson
    > <> wrote:
    >> I have an array that's sorted from highest value to lowest. I also want
    >> to insert a value in sort order, but only if the value doesn't exist
    >> already. I ended up with a solution (writing from memory here, it was on
    >> another computer) that feels a bit "long" for Ruby code, going something
    >> like this:
    >>
    >> ---
    >> arr = [5, 3, 1]
    >> insert_value = 2
    >>
    >> arr.each_index {|v, i|
    >> break if v == insert_value
    >> if insert_value > v
    >> arr.insert(i, insert_value)
    >> break
    >> end}
    >>
    >> ---
    >>
    >> Is there a "simpler" solution?
    >>
    >> Best regards,
    >>
    >> Jari Williamsson

    >
    > I guess it depends on how much efficiency you need. You could always
    > do:
    >
    > arr = [5, 3, 1]
    > insert_value = 2
    > (arr << insert_value).uniq!
    > arr.sort!.reverse!


    Thanks for the tip! I optimized it into:

    arr = [5, 3, 1]
    insert_value = 2
    arr.sort! { |a,b| b <=> a } if !(arr << insert_value).uniq!


    (Only sorts on no-duplicate and sort in correct direction first time
    around.)


    Best regards,

    Jari Williamsson
     
    Jari Williamsson, Dec 8, 2007
    #3
  4. Jari Williamsson

    Gary Wright Guest

    On Dec 8, 2007, at 3:27 PM, Jari Williamsson wrote:
    > Thanks for the tip! I optimized it into:
    >
    > arr = [5, 3, 1]
    > insert_value = 2
    > arr.sort! { |a,b| b <=> a } if !(arr << insert_value).uniq!


    That is a lot of work to insert an item into a sorted array.

    Ruby 1.9 has find_index which makes it easy to locate an
    insert position. Based on that here are some ideas:

    class Array
    if RUBY_VERSION < "1.9.0"
    def find_index(miss=nil)
    each_with_index { |e,i| return i if yield(e) }
    miss
    end
    end

    def insert_when(x)
    pos = find_index { |e| yield(e, x) }
    insert(pos, x) if pos
    self
    end
    end

    a = [1,3,5]

    a.insert_when(4) {|e, x| e >= x } # [1,3,4,5]
    a.insert_when(4) {|e, x| e >= x } # [1,3,4,4,5]

    a.insert_when(3) {|e, x|
    break if e == x
    e > x
    } # [1,3,4,4,5]
     
    Gary Wright, Dec 8, 2007
    #4
  5. Jari Williamsson

    Gary Wright Guest

    On Dec 8, 2007, at 5:03 PM, Mike Dershowitz wrote:

    > array.sort_by won't work becuase it's not a hash (although i tried
    > adding a hash and then sorting by that hash, but that didn't work
    > either
    > (got a nomethod error).
    >


    I'm not sure why you are looking for a hash.

    data = [
    [ "model1", "instance of 1", Time.now],
    [ "model2", "instance of 2", Time.now - 100]
    ]

    p data.sort_by { |x| x[2] } # => [["model2", "instance of 2", Sat
    Dec 08 17:15:41 -0500 2007], ["model1", "instance of 1", Sat Dec 08
    17:17:21 -0500 2007]]


    Gary Wright
     
    Gary Wright, Dec 8, 2007
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jason
    Replies:
    5
    Views:
    2,229
    Curt_C [MVP]
    Jun 10, 2004
  2. =?Utf-8?B?QW5hY2hvc3RpYw==?=

    RE: Textbox postback putting value,value

    =?Utf-8?B?QW5hY2hvc3RpYw==?=, Jun 18, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    656
    =?Utf-8?B?S2VpdGggRG9yYW4=?=
    Jun 21, 2004
  3. Saurabh
    Replies:
    6
    Views:
    4,617
    Chris Smith
    May 30, 2004
  4. Matthias Pfeifer

    Have std::map sorted by value

    Matthias Pfeifer, Aug 27, 2007, in forum: C++
    Replies:
    7
    Views:
    763
    Jeff F
    Aug 29, 2007
  5. Vlad Dogaru

    Putting an int value in a char array

    Vlad Dogaru, May 2, 2008, in forum: C Programming
    Replies:
    6
    Views:
    850
    Vlad Dogaru
    May 3, 2008
Loading...

Share This Page