# Array sorting question

**URL:** <https://www.ruby-forum.com/t/array-sorting-question/74987>\
**Category:** Ruby\
**Created:** [November 7, 2006, 11:05am UTC](https://www.ruby-forum.com/t/array-sorting-question/74987 "2006-11-07T11:05:09Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Giles\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/848f3c/32.png) [@Giles\_B](https://www.ruby-forum.com/u/Giles_B)\
**Post date:** [November 7, 2006, 11:05am UTC](https://www.ruby-forum.com/t/array-sorting-question/74987/1 "2006-11-07T11:05:09Z")

</div>

I have an array of arrays. the interior arrays can be of any arbitrary  
length including zero. I want to sort the array of arrays in such a  
way that the interior arrays with the most elements are closest to the  
middle of the main array.

so if it comes out like this:  
main[0] = [1, 2, 3, 4, 5]  
main[1] = []  
main [2] = []  
main [3] = [1, 2]

then that’s wrong. but it’s good if it looks like this:

main[0] = []  
main[1] = [1, 2]  
main[2] = [1, 2, 3, 4, 5]  
main[3] = []

and of course it should scale with more data to produce pyramids.

wait a minute. is this the Tower of Hanoi?

any and all suggestions welcome. I’m going to look up the Tower of  
Hanoi. I think that’s what it is.

---

<div class="post-metadata">

**Author:** ![Giles\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/848f3c/32.png) [@Giles\_B](https://www.ruby-forum.com/u/Giles_B)\
**Post date:** [November 7, 2006, 11:05am UTC](https://www.ruby-forum.com/t/array-sorting-question/74987/2 "2006-11-07T11:05:12Z")

</div>

ok, cancel that, this is not the tower of hanoi, this is splitting an  
array in half, sorting both halves, and reversing one before putting  
it back together. doh!!

---

<div class="post-metadata">

**Author:** ![Giles\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/848f3c/32.png) [@Giles\_B](https://www.ruby-forum.com/u/Giles_B)\
**Post date:** [November 7, 2006, 11:05am UTC](https://www.ruby-forum.com/t/array-sorting-question/74987/3 "2006-11-07T11:05:17Z")

</div>

Giles B. wrote:

> > so if it comes out like this:  
> > main[3] = []  
> > [http://www.gilesgoatboy.org](http://www.gilesgoatboy.org)
> 
> –  
> Giles B.  
> [http://www.gilesgoatboy.org](http://www.gilesgoatboy.org)

Actually, it’s not even that.  
If the arrays are populated in an asymetric way, then you could get one  
half of the array with much higher values than the other, which might  
not be what you want.

A better approach might be like this…

main\_array = [  
[1,2,3,1,2],  
[1,1],  
[],  
[2],  
[5,4,3,2,1,1,3],  
[5,5,3,2,1],  
[1]]

sorted\_array = main\_array.sort\_by {|x| x.size}

final\_array = []  
sorted\_array.reverse.each\_with\_index do |item, i|  
final\_array.insert(-1\*(i%2), item)  
end

puts final\_array.inspect

---

<div class="post-metadata">

**Author:** ![Giles\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/848f3c/32.png) [@Giles\_B](https://www.ruby-forum.com/u/Giles_B)\
**Post date:** [November 7, 2006, 11:05am UTC](https://www.ruby-forum.com/t/array-sorting-question/74987/4 "2006-11-07T11:05:25Z")

</div>

Giles B. wrote:

> ok, cancel that, this is not the tower of hanoi, this is splitting an  
> array in half, sorting both halves, and reversing one before putting  
> it back together. doh!!

As shown in my solution, I think the better answer is sorting the full  
array by the length of the sub arrays, and then splitting it into two  
arrays of every other item, and then (as you say) reversing one of them  
before putting it back together.

---

<div class="post-metadata">

**Author:** ![Giles\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/848f3c/32.png) [@Giles\_B](https://www.ruby-forum.com/u/Giles_B)\
**Post date:** [November 7, 2006, 11:08am UTC](https://www.ruby-forum.com/t/array-sorting-question/74987/5 "2006-11-07T11:08:50Z")

</div>

wow, both these solutions look better than what I have, and I don’t  
understand either one of them.

so Phrogz your solution is very similar to mine, except you do the  
split after the sort instead of before it? I do have to preserve the  
nested arrays intact.

I think I should say, this is a real-world thing, the arrays aren’t  
really of numbers, they’re of objects. I’m not sure if that makes a  
difference, though.

hmm, bit too brain-fried to follow all this at the moment, but  
definitely thanks for the guidance, I’ll see what I can learn from  
these.

---

<div class="post-metadata">

**Author:** ![Giles\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/848f3c/32.png) [@Giles\_B](https://www.ruby-forum.com/u/Giles_B)\
**Post date:** [November 10, 2006, 8:03am UTC](https://www.ruby-forum.com/t/array-sorting-question/74987/6 "2006-11-10T08:03:26Z")

</div>

you know, both these solutions, while much prettier than my code,  
produced messier results. here’s what I used.

```
stuff = data_objects[thing_name]
if 2 < stuff.length
  midpoint = stuff.length / 2
  left_side = stuff[0..midpoint]
  right_side = stuff[(midpoint + 1)..10000000]
  [left_side, right_side].each do |things|
    things.sort! {|x,y| x.inner_stuff.length <=> 

```

y.inner\_stuff.length}  
end  
stuff = left\_side + right\_side.reverse  
end

there’s some graphing of the results, which is why I named the vars  
left side and right side. anyway, as I said, the suggestions were much  
much prettier than my code. but for some reason the results, in the  
graph this thing produces as output, were prettier.

I really don’t know why this ugly, hackish code produces prettier  
results, but it does. it’s kind of weird that way.

---

<div class="post-metadata">

**Author:** ![Giles\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/848f3c/32.png) [@Giles\_B](https://www.ruby-forum.com/u/Giles_B)\
**Post date:** [November 7, 2006, 11:05am UTC](https://www.ruby-forum.com/t/array-sorting-question/74987/7 "2006-11-07T11:05:24Z")

</div>

Giles B. wrote:

> I have an array of arrays. the interior arrays can be of any arbitrary  
> length including zero. I want to sort the array of arrays in such a  
> way that the interior arrays with the most elements are closest to the  
> middle of the main array.

main = (-4…12).map{ |i| (0…i).to\_a }

sorted = main.sort\_by{ |sub| sub.length }  
i = 0  
half1, half2 = sorted.partition{ (i+=1) % 2 == 0 }  
pyramid = half1 + half2.reverse

require ‘pp’  
pp pyramid

#=\> [[],  
#=\> [],  
#=\> [0, 1],  
#=\> [0, 1, 2, 3],  
#=\> [0, 1, 2, 3, 4, 5],  
#=\> [0, 1, 2, 3, 4, 5, 6, 7],  
#=\> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],  
#=\> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],  
#=\> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],  
#=\> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],  
#=\> [0, 1, 2, 3, 4, 5, 6, 7, 8],  
#=\> [0, 1, 2, 3, 4, 5, 6],  
#=\> [0, 1, 2, 3, 4],  
#=\> [0, 1, 2],  
#=\> [0],  
#=\> [],  
#=\> []]
