Putting value in sorted array

  • Thread starter Jari Williamsson
  • Start date
J

Jari Williamsson

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
 
Y

yermej

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!
 
J

Jari Williamsson

yermej said:
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
 
G

Gary Wright

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]
 
G

Gary Wright

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top