how to sort a multi-elements array

Discussion in 'Ruby' started by Erwin, May 31, 2008.

  1. Erwin

    Erwin Guest

    I know how to sort an array with 2 elements... that's the only example
    I could fin on Array#sort...
    but what if ... I need to sort an array like this one :

    anArray = [ [1, "joe", 4], [2, "arthur", 2], [5, "william", 3], [16,
    "bob", 1], [20, "ernesto", 17], [27, "julia", 1], [28, "barbara", 2] ]

    sorting on third-element (highest ranking) , and second-element
    (nickname)

    aSortedArray = [ [20, "ernesto", 17], [1, "joe", 4], 5, "william", 3],
    [2, "arthur", 2], [28, "barbara", 2], [16, "bob", 1] ]

    any doc link where this is explained ?

    thanks a lot for your tip
    Erwin, May 31, 2008
    #1
    1. Advertising

  2. On 31.05.2008 19:31, Erwin wrote:
    > I know how to sort an array with 2 elements... that's the only example
    > I could fin on Array#sort...
    > but what if ... I need to sort an array like this one :
    >
    > anArray = [ [1, "joe", 4], [2, "arthur", 2], [5, "william", 3], [16,
    > "bob", 1], [20, "ernesto", 17], [27, "julia", 1], [28, "barbara", 2] ]
    >
    > sorting on third-element (highest ranking) , and second-element
    > (nickname)
    >
    > aSortedArray = [ [20, "ernesto", 17], [1, "joe", 4], 5, "william", 3],
    > [2, "arthur", 2], [28, "barbara", 2], [16, "bob", 1] ]
    >
    > any doc link where this is explained ?


    As always, use #sort with a block or #sort_by - the number of elements
    in those arrays is irrelevant, you just need to decide which elements
    you want to pick as sort key.

    an_array.sort_by {|a,b,c| [c,b]}
    an_array.sort {|(a,b,c),(d,e,f)| [c,b] <=> [f,e]}
    an_array.sort do |(a,b,c),(d,e,f)|
    x = c <=> f
    x == 0 ? b <=> e : x
    end

    Btw, your data looks like it could benefit from using Struct and also
    benefit from the automatically implemented <=>, i.e.

    Person = Struct.new :age, :name, :position

    an_array = [
    Person.new(4, "joe", 1),
    Person.new(2, "arthur", 2),
    Person.new(3, "william", 5),
    ]

    Kind regards

    robert
    Robert Klemme, May 31, 2008
    #2
    1. Advertising

  3. On Saturday 31 May 2008, Erwin wrote:
    > I know how to sort an array with 2 elements... that's the only example
    > I could fin on Array#sort...
    > but what if ... I need to sort an array like this one :
    >
    > anArray = [ [1, "joe", 4], [2, "arthur", 2], [5, "william", 3], [16,
    > "bob", 1], [20, "ernesto", 17], [27, "julia", 1], [28, "barbara", 2] ]
    >
    > sorting on third-element (highest ranking) , and second-element
    > (nickname)
    >
    > aSortedArray = [ [20, "ernesto", 17], [1, "joe", 4], 5, "william", 3],
    > [2, "arthur", 2], [28, "barbara", 2], [16, "bob", 1] ]
    >
    > any doc link where this is explained ?
    >
    > thanks a lot for your tip


    You can do this:

    aSortedArray = anArray.sort do |a, b|
    if a[2] == b[2] then a[1] <=> b[1]
    else a[2] <=> b[2]
    end
    end

    If the third element of the two subarrays are equal, then the block returns
    the result of the comparison of the second elements (using <=>), otherwise it
    returns the result of the comparison of the third elements, again using <=>.

    I hope this helps

    Stefano
    Stefano Crocco, May 31, 2008
    #3
  4. Erwin

    Erwin Guest

    On 31 mai, 19:40, Robert Klemme <> wrote:
    > On 31.05.2008 19:31, Erwin wrote:
    >
    > > I know how to sort an array with 2 elements... that's the only example
    > > I could fin on Array#sort...
    > > but what if ... I need to sort an array like this one :

    >
    > > anArray = [ [1, "joe", 4], [2, "arthur", 2], [5, "william", 3], [16,
    > > "bob", 1], [20, "ernesto", 17], [27, "julia", 1], [28, "barbara", 2] ]

    >
    > > sorting on third-element (highest ranking) , and second-element
    > > (nickname)

    >
    > > aSortedArray = [ [20, "ernesto", 17], [1, "joe", 4], 5, "william", 3],
    > > [2, "arthur", 2], [28, "barbara", 2], [16, "bob", 1] ]

    >
    > > any doc link where this is explained ?

    >
    > As always, use #sort with a block or #sort_by - the number of elements
    > in those arrays is irrelevant, you just need to decide which elements
    > you want to pick as sort key.
    >
    > an_array.sort_by {|a,b,c| [c,b]}
    > an_array.sort {|(a,b,c),(d,e,f)| [c,b] <=> [f,e]}
    > an_array.sort do |(a,b,c),(d,e,f)|
    > x = c <=> f
    > x == 0 ? b <=> e : x
    > end
    >
    > Btw, your data looks like it could benefit from using Struct and also
    > benefit from the automatically implemented <=>, i.e.
    >
    > Person = Struct.new :age, :name, :position
    >
    > an_array = [
    > Person.new(4, "joe", 1),
    > Person.new(2, "arthur", 2),
    > Person.new(3, "william", 5),
    > ]
    >
    > Kind regards
    >
    > robert


    thanks Robert , I'll write that in my NoteTaker Ruby book !!
    Erwin, Jun 1, 2008
    #4
  5. Hi,

    Was going through these older posts and have a similar question. I
    have a nested array that contains a date and a filename. I'm trying to
    sort by file date.

    The array is in the form:

    SortedFiles = [ [200904031109, "filea.txt"], [200904031337,
    "fileb.txt"], [200904031110, "filec.xt"] ]

    What I was trying to do was:

    SortedFiles.sort { |[[a,b],[x,y]] a < x | }

    That, unfortunately, did not work. I'm using Ruby 1.8.5 btw. Can anyone
    help out?

    Thanks,
    Alex

    Stefano Crocco wrote:
    > On Saturday 31 May 2008, Erwin wrote:
    >> aSortedArray = [ [20, "ernesto", 17], [1, "joe", 4], 5, "william", 3],
    >> [2, "arthur", 2], [28, "barbara", 2], [16, "bob", 1] ]
    >>
    >> any doc link where this is explained ?
    >>
    >> thanks a lot for your tip

    >
    > You can do this:
    >
    > aSortedArray = anArray.sort do |a, b|
    > if a[2] == b[2] then a[1] <=> b[1]
    > else a[2] <=> b[2]
    > end
    > end
    >
    > If the third element of the two subarrays are equal, then the block
    > returns
    > the result of the comparison of the second elements (using <=>),
    > otherwise it
    > returns the result of the comparison of the third elements, again using
    > <=>.
    >
    > I hope this helps
    >
    > Stefano


    --
    Posted via http://www.ruby-forum.com/.
    Alexey Zilber, Apr 7, 2009
    #5
  6. On 4/6/09, Alexey Zilber <> wrote:
    > Hi,
    >
    > Was going through these older posts and have a similar question. I
    > have a nested array that contains a date and a filename. I'm trying to
    > sort by file date.
    >
    > The array is in the form:
    >
    > SortedFiles = [ [200904031109, "filea.txt"], [200904031337,
    > "fileb.txt"], [200904031110, "filec.xt"] ]
    >
    > What I was trying to do was:
    >
    > SortedFiles.sort { |[[a,b],[x,y]] a < x | }
    >
    > That, unfortunately, did not work. I'm using Ruby 1.8.5 btw. Can anyone
    > help out?


    SortedFiles.sort_by {|date, fname| date}
    or:
    SortedFiles.sort {|record1,record2| record1[0]<=>record2[0]}
    Christopher Dicely, Apr 7, 2009
    #6
  7. [Note: parts of this message were removed to make it a legal post.]

    On Tue, Apr 7, 2009 at 12:31 AM, Christopher Dicely <>wrote:

    > On 4/6/09, Alexey Zilber <> wrote:
    > > Hi,
    > >
    > > Was going through these older posts and have a similar question. I
    > > have a nested array that contains a date and a filename. I'm trying to
    > > sort by file date.
    > >
    > > The array is in the form:
    > >
    > > SortedFiles = [ [200904031109, "filea.txt"], [200904031337,
    > > "fileb.txt"], [200904031110, "filec.xt"] ]
    > >
    > > What I was trying to do was:
    > >
    > > SortedFiles.sort { |[[a,b],[x,y]] a < x | }
    > >
    > > That, unfortunately, did not work. I'm using Ruby 1.8.5 btw. Can anyone
    > > help out?

    >
    > SortedFiles.sort_by {|date, fname| date}
    > or:
    > SortedFiles.sort {|record1,record2| record1[0]<=>record2[0]}
    >
    >

    Since you are sorting on the first element of each array you can just use
    SortedFiles.sort

    Array comparison with another array works by using the comparison of the
    first pair of elements which aren't equal, so [1,1] < [2,0] < [2,1]


    --
    Rick DeNatale

    Blog: http://talklikeaduck.denhaven2.com/
    Twitter: http://twitter.com/RickDeNatale
    WWR: http://www.workingwithrails.com/person/9021-rick-denatale
    LinkedIn: http://www.linkedin.com/in/rickdenatale
    Rick DeNatale, Apr 7, 2009
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Abby
    Replies:
    2
    Views:
    596
  2. rkk
    Replies:
    9
    Views:
    797
    CBFalconer
    Sep 24, 2006
  3. Navin
    Replies:
    1
    Views:
    659
    Ken Schaefer
    Sep 9, 2003
  4. GIMME
    Replies:
    5
    Views:
    174
    Thomas 'PointedEars' Lahn
    Jul 26, 2004
  5. Domenico Discepola

    multi-field array sort using Sort::Fields method

    Domenico Discepola, Apr 27, 2004, in forum: Perl Misc
    Replies:
    6
    Views:
    287
    Uri Guttman
    Apr 28, 2004
Loading...

Share This Page