# Sorting using many subitems

Hi
Is there something better than writing
a.sort_by {|x| x[0]} . sort_by { |x| x[1] } ... # just in one sort?

Example: a=[['Hello', 3, :ee], ['bye', 5, :ff ]

thanks
Opti

PLEASE. FFS. Be a good mailing list citizen and start new threads instead of just renaming subject lines. I believe I’ve seen this written to you at least 3 times now…

There exists Array#sort. Use that in sort_by:

a.sort_by { |x| [x[1], x[0]] }

···

On Jan 3, 2017, 14:30 -0800, Die Optimisten <inform@die-optimisten.net>, wrote:

Hi
Is there something better than writing
a.sort_by {|x| x[0]} . sort_by { |x| x[1] } ... # just in one sort?

Example: a=[['Hello', 3, :ee], ['bye', 5, :ff ]

According to Enumerable#sort_by "The result is not guaranteed stable. When
two keys are equal, the order of the corresponding element is
unpredictable."

So effectively you've written: a.sort_by{|x| x.last }

If you mean something else; for example to sort by the first element, and
resolve ties using the second element:

···

On 4 January 2017 at 08:29, Die Optimisten <inform@die-optimisten.net> wrote:

Hi
Is there something better than writing
a.sort_by {|x| x[0]} . sort_by { |x| x[1] } ... # just in one sort?

Example: a=
​​
[['Hello', 3, :ee], ['bye', 5, :ff ]

thanks
Opti

~~~
a = [["a", 1, :z], ["a", 1, :x], ["b", 0, :x]]
a.sort
#=> [["a", 1, :x], ["a", 1, :z], ["b", 0, :x]]
~~~

Or if you want the reverse (which is closest to what you originally posted):

~~~
a = [["a", 1, :z], ["a", 1, :x], ["b", 0, :x]]
a.sort_by {|x| x.reverse }
#=> [["b", 0, :x], ["a", 1, :x], ["a", 1, :z]]
~~~

It's hard to say what you really want, though, since your original example
is broken.

Cheers
--
Matthew Kerwin
http://matthew.kerwin.net.au/

Is there something better than writing
a.sort_by {|x| x[0]} . sort_by { |x| x[1] } ... # just in one sort?

Example: a=[['Hello', 3, :ee], ['bye', 5, :ff ]

Please have a closer look at my last response to your
"Umlauts" / "Re: sorting array" thread:

Try this:

a.sort_by {|x| x =~ /(\w):(\d)/; [\$2, \$1] }

You can sort using an array.

Regards,
Marcus

···

Am 03.01.2017 um 23:29 schrieb Die Optimisten:

Hi!
Thanks for these examples!
its about the concatenation of more sort_bys (sorting different fields;
I hoped that sorting identical content would preserve the order as it is?!
So (I hope?!) the answer from Ryan solved this; I didn't expect that to work, because
arr < arr is not supported.

Opti

···

On 2017-01-03 23:43, Matthew Kerwin wrote:

On 4 January 2017 at 08:29, Die Optimisten <inform@die-optimisten.net > <mailto:inform@die-optimisten.net>> wrote:

Hi
Is there something better than writing
a.sort_by {|x| x[0]} . sort_by { |x| x[1] } ... # just in one sort?

Example: a=
​ ​
[['Hello', 3, :ee], ['bye', 5, :ff ]

thanks
Opti

According to Enumerable#sort_by "The result is not guaranteed stable. When two keys are equal, the order of the corresponding element is unpredictable."

So effectively you've written: a.sort_by{|x| x.last }

If you mean something else; for example to sort by the first element, and resolve ties using the second element:

~~~
a = [["a", 1, :z], ["a", 1, :x], ["b", 0, :x]]
a.sort
#=> [["a", 1, :x], ["a", 1, :z], ["b", 0, :x]]
~~~

Or if you want the reverse (which is closest to what you originally posted):

~~~
a = [["a", 1, :z], ["a", 1, :x], ["b", 0, :x]]
a.sort_by {|x| x.reverse }
#=> [["b", 0, :x], ["a", 1, :x], ["a", 1, :z]]
~~~

It's hard to say what you really want, though, since your original example is broken.

Cheers
--
Matthew Kerwin
http://matthew.kerwin.net.au/

The whole approach is broken and inefficient. If you need to order by
multiple values then you still only need _one_ sort call - whether it
is #sort or #sort_by. Which one depends on the concrete case but
concatenating is not the right option.

Cheers

robert

···

On Tue, Jan 3, 2017 at 11:50 PM, Die Optimisten <inform@die-optimisten.net> wrote:

its about the concatenation of more sort_bys (sorting different fields;

--
[guy, jim, charlie].each {|him| remember.him do |as, often| as.you_can
- without end}
http://blog.rubybestpractices.com/

Hi
Is there something better than writing
a.sort_by {|x| x[0]} . sort_by { |x| x[1] } ... # just in one sort?

Example: a=
​ ​
[['Hello', 3, :ee], ['bye', 5, :ff ]

thanks
Opti

According to Enumerable#sort_by "The result is not guaranteed stable. When
two keys are equal, the order of the corresponding element is
unpredictable."

So effectively you've written: a.sort_by{|x| x.last }

If you mean something else; for example to sort by the first element, and
resolve ties using the second element:

~~~
a = [["a", 1, :z], ["a", 1, :x], ["b", 0, :x]]
a.sort
#=> [["a", 1, :x], ["a", 1, :z], ["b", 0, :x]]
~~~

Or if you want the reverse (which is closest to what you originally
posted):

~~~
a = [["a", 1, :z], ["a", 1, :x], ["b", 0, :x]]
a.sort_by {|x| x.reverse }
#=> [["b", 0, :x], ["a", 1, :x], ["a", 1, :z]]
~~~

It's hard to say what you really want, though, since your original example
is broken.

Cheers
--
Matthew Kerwin
http://matthew.kerwin.net.au/

Hi!
Thanks for these examples!
its about the concatenation of more sort_bys (sorting different fields;

​Yeah, but without knowing exactly how you're comparing them, there's no
way to show you other ways. If you want even more pair-wise control have a
look at Array#zip and Array#sort's block mode.​

I hoped that sorting identical content would preserve the order as it is?!

​It may do now, in this version of Ruby, but it is not guaranteed. If you
want to depend on that sort of ordering you need to construct a more
specific #sort_by​

So (I hope?!) the answer from Ryan solved this; I didn't expect that to
work, because
arr < arr is not supported.

​Sorting uses #<=> rather than #<​

···

On 4 January 2017 at 08:50, Die Optimisten <inform@die-optimisten.net> wrote:

On 2017-01-03 23:43, Matthew Kerwin wrote:
On 4 January 2017 at 08:29, Die Optimisten <inform@die-optimisten.net> > wrote:

--
Matthew Kerwin
http://matthew.kerwin.net.au/

a.sort_by {|x| x =~ /(\w):(\d)/; [\$2, \$1] }

Example?

···

On Wed, 4 Jan 2017 at 09:24, stomar <sto.mar@web.de> wrote:

Am 03.01.2017 um 23:29 schrieb Die Optimisten:

> Is there something better than writing

> a.sort_by {|x| x[0]} . sort_by { |x| x[1] } ... # just in one sort?

>

> Example: a=[['Hello', 3, :ee], ['bye', 5, :ff ]

Please have a closer look at my last response to your

"Umlauts" / "Re: sorting array" thread:

> Try this:

>

> a.sort_by {|x| x =~ /(\w):(\d)/; [\$2, \$1] }

You can sort using an array.

Regards,

Marcus

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>

Sorry, I meant where can we find the documentation for the:

I see. It sorts by \$2 which is the second match and then by \$1 which is the
first match.
Clever!

···

On Wed, 4 Jan 2017 at 09:48, Daniel Ferreira <subtileos@gmail.com> wrote:

On Wed, 4 Jan 2017 at 09:24, stomar <sto.mar@web.de> wrote:

Am 03.01.2017 um 23:29 schrieb Die Optimisten:

> Is there something better than writing

> a.sort_by {|x| x[0]} . sort_by { |x| x[1] } ... # just in one sort?

>

> Example: a=[['Hello', 3, :ee], ['bye', 5, :ff ]

Please have a closer look at my last response to your

"Umlauts" / "Re: sorting array" thread:

> Try this:

>

> a.sort_by {|x| x =~ /(\w):(\d)/; [\$2, \$1] }

You can sort using an array.

Regards,

Marcus

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>

Sorry, I meant where can we find the documentation for the:

a.sort_by {|x| x =~ /(\w):(\d)/; [\$2, \$1] }

Example?

Sorry, I meant where can we find the documentation for the:

a.sort_by {|x| x =~ /(\w):(\d)/; [\$2, \$1] }

Example?

Seems this is not documented anywhere?
( \$n can be used after /re/; )

Opti

Hi
So the question for optimization (of concatenated sort_bys)
But what to do if ordering is not guaranteed to be preserved for identical values?

thanks
Opti

···

On 2017-01-04 08:02, Robert Klemme wrote:

On Tue, Jan 3, 2017 at 11:50 PM, Die Optimisten > <inform@die-optimisten.net> wrote:

its about the concatenation of more sort_bys (sorting different fields;

The whole approach is broken and inefficient. If you need to order by
multiple values then you still only need _one_ sort call - whether it
is #sort or #sort_by. Which one depends on the concrete case but
concatenating is not the right option.

Cheers

robert

No, stability is still not guaranteed;
it also depends on the OS, via the used libraries, AFAIK.

Regards,
Marcus

···

Am 03.01.2017 um 23:57 schrieb Matthew Kerwin:

I hoped that sorting identical content would preserve the order as
it is?!

​It may do now, in this version of Ruby, but it is not guaranteed. If
you want to depend on that sort of ordering you need to construct a more
specific #sort_by​

Sorry, I meant where can we find the

documentation for the:

a.sort_by {|x| x =~ /(\w):(\d)/; [\$2,

\$1] }

Example?

Seems this is not documented anywhere?

( \$n can be used after /re/; )

Opti

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>

Search for \$1 or \$2 in the ruby Regexp class documentation. It is there.

···

On Wed, 4 Jan 2017 at 13:29, Die Optimisten <inform@die-optimisten.net> wrote:

Note that with a single #sort or #sort_by you will compare multiple
fields in one go which reduces the likelihood of identical values. If
you still want to be absolutely sure the original order for identical
items is retained then you can add more fields insert an arbitrary
value for the position and include that in the comparison:

i = 0
sorted = enum.sort_by {|e| [e.foo, e.bar, i += 1]}

Regards

robert

···

On Wed, Jan 4, 2017 at 2:44 PM, Die Optimisten <inform@die-optimisten.net> wrote:

On 2017-01-04 08:02, Robert Klemme wrote:

On Tue, Jan 3, 2017 at 11:50 PM, Die Optimisten >> <inform@die-optimisten.net> wrote:

its about the concatenation of more sort_bys (sorting different fields;

The whole approach is broken and inefficient. If you need to order by
multiple values then you still only need _one_ sort call - whether it
is #sort or #sort_by. Which one depends on the concrete case but
concatenating is not the right option.

So the question for optimization (of concatenated sort_bys)
But what to do if ordering is not guaranteed to be preserved for identical
values?

--
[guy, jim, charlie].each {|him| remember.him do |as, often| as.you_can
- without end}
http://blog.rubybestpractices.com/

Since you yourself brought up regular expressions, grouping
and the \$1, \$2 variables in the other thread, I do not really
understand what you think is not documented.

Regards,
Marcus

···

Am 04.01.2017 um 14:29 schrieb Die Optimisten:

Seems this is not documented anywhere?
( \$n can be used after /re/; )

--
GitHub: https://github.com/stomar/
PGP: 0x6B3A101A

Where can we find the documentation for that?

···

On Wed, 4 Jan 2017 at 09:27, stomar <sto.mar@web.de> wrote:

Am 03.01.2017 um 23:57 schrieb Matthew Kerwin:

> I hoped that sorting identical content would preserve the order as

> it is?!

>

>

> ​It may do now, in this version of Ruby, but it is not guaranteed. If

> you want to depend on that sort of ordering you need to construct a more

> specific #sort_by​

No, stability is still not guaranteed;

it also depends on the OS, via the used libraries, AFAIK.

Regards,

Marcus

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>