[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Putting value in sorted array

Jari Williamsson

12/8/2007 5:48:00 PM

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

4 Answers

yermej

12/8/2007 7:51:00 PM

0

On Dec 8, 11:48 am, Jari Williamsson
<jari.williams...@mailbox.swipnet.se> 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!

Jari Williamsson

12/8/2007 8:27:00 PM

0

yermej wrote:
> On Dec 8, 11:48 am, Jari Williamsson
> <jari.williams...@mailbox.swipnet.se> 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

Gary Wright

12/8/2007 10:49:00 PM

0


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

12/8/2007 10:51:00 PM

0


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