🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.ruby
6 messages
6 total messages Started by Jaroslaw Zabiello Fri, 09 Feb 2007 14:03
Wielowymiarowe sortowanie listy haszy
#428
Author: Jaroslaw Zabiello
Date: Fri, 09 Feb 2007 14:03
24 lines
1329 bytes
Chciałbym posortować listę haszy wg klucza :level1, a następnie wg klucza
:level2. Np. mam takie dane

items = [ 
  {:level1=>'b',:x=>'B1',:level2=>1},  
  {:level1=>'c',:x=>'C1',:level2=>1},  
  {:level1=>'c',:x=>'C2',:level2=>2},  
  {:level1=>'a',:x=>'A1',:level2=>1},
  {:level1=>'a',:x=>'A3',:level2=>3},
  {:level1=>'a',:x=>'A2',:level2=>2},
]  

Sortowanie wg jednego poziomu jest proste

items = items.sort_by do |item| 
  item[:level1]
end

Da się jakoś ten blok uzupełnić o sortowanie wewnatrzne wg kolejnego
poziomu?

-- 
Jarosław Zabiełło
http://blog.zabiello.com
Re: Wielowymiarowe sortowanie listy haszy
#429
Author: hubert depesz lubaczewski
Date: Fri, 09 Feb 2007 15:14
21 lines
1452 bytes
On 2007-02-09, Jaroslaw Zabiello <hipertracker@gmail.com> wrote:
> Da się jakoś ten blok uzupełnić o sortowanie wewnatrzne wg kolejnego
> poziomu?

jasne.
zobacz do ri sort_by.
podpowiadają:

sorted = files.sort {|a,b| File.new(a).mtime <=> File.new(b).mtime}
skoro można tak (aczkolwiek to do tablic, nie wiem czy do haszy
zadziala - gdyby nie to hash.keys.sort { }):
a <=> b || a.length <=> b.length

powinno ładnie zadziałać.

depesz

-- 
quicksil1er: "postgres is excellent, but like any DB it requires a
highly paid DBA.  here's my CV!" :)
http://www.depesz.com/ - blog dla ciebie (i moje CV)
Re: Wielowymiarowe sortowanie listy haszy
#430
Author: Marcin Mielżyński
Date: Fri, 09 Feb 2007 15:18
15 lines
1195 bytes
Jaroslaw Zabiello wrote:

> 
> items = items.sort_by do |item| 
>   item[:level1]
     [item[:level1],item[:level2]]	
> end
> 
> Da się jakoś ten blok uzupełnić o sortowanie wewnatrzne wg kolejnego
> poziomu?
> 

ale da się wydajniej (choć sort_by i tak robi swartzian transform)

lopex
Re: Wielowymiarowe sortowanie listy haszy
#431
Author: Jaroslaw Zabiello
Date: Fri, 09 Feb 2007 15:30
23 lines
1553 bytes
Dnia Fri, 09 Feb 2007 16:18:03 +0100, Marcin Mielżyński napisał(a):

>> items = items.sort_by do |item| 
>>   item[:level1]
>      [item[:level1],item[:level2]]	
>> end

A jak byłoby w sytuacji:

sort_order = ['transport', 'accommodation', 'activities', 'extras']
items = [ 
  {:level1=>'b',:x=>'B1',:service_name=>'transport'},  
  {:level1=>'c',:x=>'C1',:service_name=>'extras'},  
  {:level1=>'c',:x=>'C2',:service_name=>'transport'},  
  {:level1=>'a',:x=>'A1',:service_name=>'activities'},
  {:level1=>'a',:x=>'A3',:service_name=>'accommodation'},
  {:level1=>'a',:x=>'A2',:service_name=>'travel'},]

W tym wypadku chcę posortować wg :level1 oraz sort_order...

-- 
Jarosław Zabiełło
http://blog.zabiello.com
Re: Wielowymiarowe sortowanie listy haszy
#432
Author: Jaroslaw Zabiello
Date: Fri, 09 Feb 2007 15:52
61 lines
2766 bytes
Dnia Fri, 9 Feb 2007 15:30:26 +0000, Jaroslaw Zabiello napisał(a):

> A jak byłoby w sytuacji:
> 
> sort_order = ['transport', 'accommodation', 'activities', 'extras']
> items = [ 
>   {:level1=>'b',:x=>'B1',:service_name=>'transport'},  
>   {:level1=>'c',:x=>'C1',:service_name=>'extras'},  
>   {:level1=>'c',:x=>'C2',:service_name=>'transport'},  
>   {:level1=>'a',:x=>'A1',:service_name=>'activities'},
>   {:level1=>'a',:x=>'A3',:service_name=>'accommodation'},
>   {:level1=>'a',:x=>'A2',:service_name=>'travel'},]
> 
> W tym wypadku chcę posortować wg :level1 oraz sort_order...

W tym wypadku musiałem posiłkowac się dodatkowym polem. Być może da się
krócej...

sort_order = {
  'travel'=>1, 
  'transport'=>2, 
  'accommodation'=>3, 
  'activities'=>4, 
  'extras'=>5
  }
items = [ 
  {:level1=>'b',:x=>'B1',:service_name=>'transport'},  
  {:level1=>'c',:x=>'C1',:service_name=>'extras'},  
  {:level1=>'c',:x=>'C2',:service_name=>'transport'},  
  {:level1=>'a',:x=>'A1',:service_name=>'activities'},
  {:level1=>'a',:x=>'A3',:service_name=>'accommodation'},
  {:level1=>'a',:x=>'A2',:service_name=>'travel'},
  ]  

#dodaje pomocniczy klucz
items = items.map { |item| 
  item.update({ :level2 => sort_order[item[:service_name]]})
}

# sortuje wg 2 poziomow
items = items.sort_by do |item|  
  [ item[:level1],item[:level2] ]
end

# usuwam nadmiarowe klucze
items = items.map{|item| item.delete :level2; item }

# sprawdzenie
items.each {|row| p row }

#{:service_name=>"travel", :x=>"A2", :level1=>"a"}
#{:service_name=>"accommodation", :x=>"A3", :level1=>"a"}
#{:service_name=>"activities", :x=>"A1", :level1=>"a"}
#{:service_name=>"transport", :x=>"B1", :level1=>"b"}
#{:service_name=>"transport", :x=>"C2", :level1=>"c"}
#{:service_name=>"extras", :x=>"C1", :level1=>"c"}


-- 
Jarosław Zabiełło
http://blog.zabiello.com
Re: Wielowymiarowe sortowanie listy haszy
#433
Author: Marcin Mielżyński
Date: Fri, 09 Feb 2007 16:16
21 lines
1632 bytes
i = 0
sort_order = ['transport', 'accommodation', 'activities', 
'extras'].inject(Hash.new(100)){|h,v|h[v] = i+=1;h}

items = [
   {:level1=>'b',:x=>'B1',:service_name=>'transport'},
   {:level1=>'c',:x=>'C1',:service_name=>'extras'},
   {:level1=>'c',:x=>'C2',:service_name=>'transport'},
   {:level1=>'a',:x=>'A1',:service_name=>'activities'},
   {:level1=>'a',:x=>'A3',:service_name=>'accommodation'},
   {:level1=>'a',:x=>'A2',:service_name=>'travel'},]

items = items.sort_by{|e|
     [e[:level1],sort_order[e[:service_name]]]
}


nie trzeba dodatkowych kluczy, pisane na kolanie także pewnie da się 
wydajniej...

lopex
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads