# Sorting & comparing complex array

**URL:** <https://www.ruby-forum.com/t/sorting-comparing-complex-array/129222>\
**Category:** Ruby\
**Created:** [February 15, 2008, 4:20pm UTC](https://www.ruby-forum.com/t/sorting-comparing-complex-array/129222 "2008-02-15T16:20:32Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Erwin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/a88e57/32.png) [@Erwin](https://www.ruby-forum.com/u/Erwin)\
**Post date:** [February 15, 2008, 4:20pm UTC](https://www.ruby-forum.com/t/sorting-comparing-complex-array/129222/1 "2008-02-15T16:20:32Z")

</div>

As per Ruby CookBook, I learnt how to sort a simple array by  
frequency :

def sort\_by\_frequency\_descending  
histogram = inject(Hash.new(0)) { |hash, x| hash[x] += 1; hash}  
sort\_by { |x| [histogram[x] \* -1, x]}  
end  
[1,2,3,4,1,2,4,8,1,4,9,16].sort\_by\_frequency\_descending

# =\> [1, 1, 1, 4, 4, 4, 2, 2, 3, 8, 9, 16]

Q1: how should I modify this method, to manipulate more complex  
array,  
like [[1, 1, a] ,[2 , 2, b] ,[3, 4, c] , [4, 5, d] , [1, 2, e] ,  
[2, 1, f] , […  
where I should sort on the first and second value of each element

this sort\_by\_frequency\_descending is a prelude comparing sucessive  
items of the array, once it is sorted :

b\_start = [[1.0, 1.5, a1] , [1.0, 1.5, a2], [1.0, 1.5, a3], [1.0,  
1.5, a4], [2.1, 2.5, a5], [2.1, 2.5, a6], [2.1, 2.5, a7], [4.6, 4.2,  
a8], [4.6, 4.2, a9], [4.6, 4.2, a10], [8.3, 8.4, a11], [8.3, 8.4,  
a12], [9.5, 9.3, a13], [16.8, 16.7, a14] ]

when an item has first & second values identical to first & second  
values of previous item, then a proc should be applied to both values  
of second item to modify them ( \* by random)  
b\_start[i+1][0] == b\_start[i][0] && \_start[i+1][1] == b\_start[i][1]

Q2: I am not yet fluent with this kind of complex process (beyond my  
present readin status of ruby cookbook…)…  
I’ll appreciate any help

---

<div class="post-metadata">

**Author:** ![Erwin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/a88e57/32.png) [@Erwin](https://www.ruby-forum.com/u/Erwin)\
**Post date:** [February 15, 2008, 7:25pm UTC](https://www.ruby-forum.com/t/sorting-comparing-complex-array/129222/2 "2008-02-15T19:25:39Z")

</div>

On Feb 15, 10:18 am, Erwin [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Q1: how should I modify this method, to manipulate more complex  
> a8], [4.6, 4.2, a9], [4.6, 4.2, a10], [8.3, 8.4, a11], [8.3, 8.4,  
> a12], [9.5, 9.3, a13], [16.8, 16.7, a14] ]
> 
> when an item has first & second values identical to first & second  
> values of previous item, then a proc should be applied to both values  
> of second item to modify them ( \* by random)  
> b\_start[i+1][0] == b\_start[i][0] && \_start[i+1][1] == b\_start[i][1]
> 
> Q2: I am not yet fluent with this kind of complex process (beyond my  
> present readin status of ruby cookbook…)…  
> I’ll appreciate any help

For Q1 try:  
array\_of\_arrays.sort\_by{|a,b|  
if a[0] == b[0]  
a[1] \<=\> b[1]  
else  
a[0] \<=\> b[0]  
end  
}

For Q2, i’ll assume you want a new array with the changes (if any):

new\_arr\_of\_arrs = [array\_of\_arrays[0]] #first item is unchanged as no  
previous to compare to  
1.upto(array\_of\_arrays.size) { |i|  
p = i-1  
if array\_of\_arrays[p][0] == array\_of\_arrays[i][0] and  
array\_of\_arrays[p][1] == array\_of\_arrays[i][1]  
new\_arr\_of\_arrs \<\< some\_func\_retuning  
randomized\_arr\_based\_on(array\_of\_arrays[i])  
else  
new\_arr\_of\_arrs \<\< array\_of\_arrays[i]  
end  
}

I didn’t run this code so it may have syntax errors (I think the logic  
is good), but hopefully it gets you going

Cheers
