How to Sort a Ruby Array of Strings by Length

How do I sort a Ruby array of strings by length?

arr = arr.sort_by {|x| x.length}

Or in 1.8.7+:

arr = arr.sort_by(&:length)

ruby sort array by length then alphabetically

This should work:

string.split.sort_by { |e| -e.length }.group_by(&:length).map{ |_, v| v.sort.reverse }.flatten

Sorting Ruby array of array items by length evenly

The algorithm I would use to get a roughly even distribution of size, per my comment on OP:

unchunked_data = [
[{...}],
[{...}],
[{...}],
[{...}],
[{...}],
[{...}],
[{...}],
[{...}]
]

sorted_data = unchunked_data.sort_by(&:size)
grouped_data = sorted_data.each_with_index.group_by { |_, index| index % 4 }

grouped_data.each do |process_index, data|
# each_with_index would put data in an array with its index in sorted_data. Calling map(&:first) removes that index.
data_without_index = data.map(&:first)
send_data_to_process(process_index, data_without_index)
end

If the data is as it appears in OP's example, this results in a perfect distribution.


Per discussion in the comments, you can get back all the data in single array, as formatted in the original but grouped with this method, by doing:

grouped_data.values.flatten(1)

Is there a Ruby way to sort an array of strings by number of words?

You can do this with Array#sort and split, like so:

array = ["dog eats", "dog", "cat eats dog"]
=> ["dog eats", "dog", "cat eats dog"]
array.sort { |a,b| a.split.length <=> b.split.length }
=> ["dog", "dog eats", "cat eats dog"]

That sorts in ascending number of whitespace-separated words.

Edit: per @MarkReed, to reverse, reverse the order of the sort expression:

array.sort { |a,b| b.split.length <=> a.split.length }
=> ["cat eats dog", "dog eats", "dog"]

You could split on any other separator if desired.

ruby/rails sort an array of records based on an array of string

You can do as

users.sort_by { |u| priority.index(u.priority) || priority.size }

The above sorting is done, with the assumption that the below Array will be sorted as per your need, will hold all uniq values. users array then will use the index of the sorted array.

priority = ["Wednesday","Tuesday","Friday"]

index(obj) → int or nil

Returns the index of the first object in ary such that the object is == to obj. Returns nil if no match is found.

priority array doesn't hold all weekdays, rather 3. I thought, if any users has priority, which is not present in the priority array, let those users be placed in the last array. Suppose, for any user there is a priority, "Sunday", then, that user will be given lowest priority. How ?

Look at the expression priority.index(u.priority) || priority.size, now with above mentioned sample, priority.index("sunday") gives nil, and right hand side expression of the || will be evaluated, i.e. priority.size, which 3. That's how that user will be moved to the tail of the array.

Sort an Array of Strings by their Integer Values

I'll throw another method out there since it's the shortest way I can think of

a.sort_by(&:to_i)

Sorting an array of strings in Ruby

Both lines do the same (create a new array, which is reverse sorted). The main argument is about readability and performance. array.sort.reverse! is more readable than array.sort{|x,y| y<=>x} - I think we can agree here.

For the performance part, I created a quick benchmark script, which gives the following on my system (ruby 1.9.3p392 [x86_64-linux]):

                              user     system      total        real
array.sort.reverse 1.330000 0.000000 1.330000 ( 1.334667)
array.sort.reverse! 1.200000 0.000000 1.200000 ( 1.198232)
array.sort!.reverse! 1.200000 0.000000 1.200000 ( 1.199296)
array.sort{|x,y| y<=>x} 5.220000 0.000000 5.220000 ( 5.239487)

Run times are pretty constant for multiple executions of the benchmark script.

array.sort.reverse (with or without !) is way faster than array.sort{|x,y| y<=>x}. Thus, I recommend that.


Here is the script as a Reference:

#!/usr/bin/env ruby
require 'benchmark'

Benchmark.bm do|b|
master = (1..1_000_000).map(&:to_s).shuffle
a = master.dup
b.report("array.sort.reverse ") do
a.sort.reverse
end

a = master.dup
b.report("array.sort.reverse! ") do
a.sort.reverse!
end

a = master.dup
b.report("array.sort!.reverse! ") do
a.sort!.reverse!
end

a = master.dup
b.report("array.sort{|x,y| y<=>x} ") do
a.sort{|x,y| y<=>x}
end
end

Sorting array of string by numbers

▶ a = ["10a","10b","9a","9b","8a","8b"]
▶ a.sort { |a,b| a.to_i == b.to_i ? a <=> b : a.to_i <=> b.to_i }
#=> [
# [0] "8a",
# [1] "8b",
# [2] "9a",
# [3] "9b",
# [4] "10a",
# [5] "10b"
#]

Hope it helps.



Related Topics



Leave a reply



Submit