originals indexes of sorted elements in Ruby

ruby sort by alphabetically
sort array of hashes ruby
ruby sort by date
ruby sort array of arrays
ruby sort hash by multiple values
ruby sort proc
ruby sort performance
ruby sort lexicographic
arr = [1,3,2,4]

arr.sort #=> [1,2,3,4]

I would like an array [0, 2, 1, 3] (original indexes in arr.sort order)

Is there a simple way to do that with Ruby 1.9.3?

thank you

xs = [1, 3, 2, 4]
original_indexes = xs.map.with_index.sort.map(&:last)
#=> [0, 2, 1, 3]

The Difference Between .sort and .sort_by in Ruby, .sort is a Ruby enumerator that compares two elements in an array at a time. Then, the keys are sorted, and mapped back onto the original values. whatever gets passed in to .index() as the argument (remember that strings, just like arrays,​  Ruby arrays are ordered, integer-indexed collections of any object. Each element in an array is associated with and referred to by an index. Array indexing starts at 0, as in C or Java. A negative index is assumed relative to the end of the array --- that is, an index of -1 indicates the last element of the array, -2 is the next to last element

arr=[1,3,2,4]
p arr.map{|e| arr.sort.index(e)}

to avoid sorting each time, better is:

arr=[1,3,2,4]
arr_s = arr.sort
p arr.map{|e| arr_s.index(e)}

UPDATED

arr=[1,3,2,4]
start_time = Time.now
(1..100000).each do |i|
    arr.map{|e| arr.sort.index(e)}
end
elapsed = Time.now - start_time
p elapsed

xs = [1, 3, 2, 4]
start_time = Time.now
(1..100000).each do |i|
    xs.map.with_index.sort.map(&:last)
end
elapsed = Time.now - start_time
p elapsed

and got the result:

0.281736
0.504314

How to Sort Arrays & Hashes in Ruby (Examples Included), The Ruby sort method helps you order your data (arrays & hashes) in the sort method, then taking a look at sort_by for advanced sorting (by multiple values) & more. This means that the original array will change instead of creating a new one, to be used as the basis for sorting (array length, object attribute, index, etc.​)  Using find_index to return first match. Profit! This example shows how to use find_index to return a result as soon as the first occurrence of what you are looking for is found.

I tested on MRI Ruby 2.2.1p85 (on both Mac and CentOS), tokland's solution return a wrong result:

xs = [8,3,2,7,5]
xs.map.with_index.sort.map(&:last)
#=> [2, 1, 4, 3, 0] # wrong

Yevgeniy Anfilofyev solution works but does not support non-unique array:

arr = [8,3,2,7,5]
arr_s = arr.sort
arr.map{|e| arr_s.index(e)}
#=> [4, 1, 0, 3, 2] # correct

arr = [8,3,5,2,8,8,7,5]
arr_s = arr.sort
arr.map{|e| arr_s.index(e)}
#=> [5, 1, 2, 0, 5, 5, 4, 2]

I come up this:

arr = [8,3,5,2,8,8,7,5]
index_order = []
arr.uniq.sort.each do |a|
  index_order += arr.each_index.select{|i| arr[i] == a }
end
r = []
index_order.each_with_index do |a, i|
  r[a] = i
end
r
#=> [5, 1, 2, 0, 6, 7, 4, 3]

Ruby Tips: Sort Methods |, sortBy default, Ruby's .sort method will sort any array of numbers or strings will shift over one index in our array and compare the next set of values. an array which is what .sort_by needs to sort our original array of words. Sort the array in a given index range Given an array arr[] of N integers and an index range [a, b] . The task is to sort the array in this given index range i.e., sort the elements of the array from arr[a] to arr[b] while keeping the positions of other elements intact and print the modified array.

array = [6, 20, 12, 2, 9, 22, 17]
sorted = array.sort
indices = []
array.each do |n|
  index = (0...sorted.length).bsearch { |x| n <=> sorted[x] }
  indices << index
end
indices

This solution works with O(nlogn)

Ruby Arrays Cheat Sheet, Ruby Arrays Cheat Sheet. < Learn These Shortcuts. Accessing Elements I. a[​index]. Element Reference - return the element at index of array a. a[n..length]. In either case, the elements of the array must be monotone (or sorted) with respect to the block. In find-minimum mode (this is a good choice for typical use cases), the block must always return true or false, and there must be an index i (0 <= i <= ary.size) so that: the block returns false for any element whose index is less than i, and

(0..arr.size - 1).sort_by { |i| arr[i] }

How To Use Array Methods in Ruby, To get a random element from an array, you could generate a random index between Both sort and sort_by return new arrays, leaving the original array intact. Given a sorted array with possibly duplicate elements, the task is to find indexes of first and last occurrences of an element x in the given array. The Naive Approach is to run a for loop and check given elements in array. Run a for loop and for i = 0 to n-1 2. Take first = -1 and last = -1 3. When we find element first time then we update

A Ruby Cheatsheet For Arrays, Simply put, before you lies a metric ton of handy Ruby Array methods. And to keep things shorter, I'll write return values in comments, so arr Get the value at an index or a default value: #fetch will return the "not found"# leave original alone by subtracting arrays useful for sorting in reverse order The index method returns the index of the array element. It returns the index of the first element from the left. The first line returns 1, which is the index of the first 2 in the array. There is only one 11 in the array and its index is 8. puts numbers.rindex 2 The rindex returns the index of the first element from the right. In our case, the rightmost 2 has index 3.

Class: Array (Ruby 2.4.2), Arrays are ordered, integer-indexed collections of any object. to create a new array based on the original array, but with the values modified by In either case​, the elements of the array must be monotone (or sorted) with respect to the block. The sort method takes a Ruby block that gives you access to elements in the array so you can compare them. To do the comparison, you use the comparison operator ( <=> ), often referred to as the spaceship operator. This operator compares two Ruby objects and returns -1 if the object on the left is smaller,

Array, Set Difference---Returns a new array that is a copy of the original array, removing Element Reference---Returns the element at index anInteger, or returns a Same as Array#sort , but modifies the receiver in place. arr is effectively frozen  The current implementation of sort_by generates an array of tuples containing the original collection element and the mapped value. This makes sort_by fairly expensive when the keysets are simple. require 'benchmark' a = ( 1 .. 100000 ). map { rand ( 100000 ) } Benchmark . bm ( 10 ) do | b | b . report ( "Sort" ) { a . sort } b . report ( "Sort

Comments
  • i don't know which solution is the fastest
  • what is the character '&' at the end of second line ?
  • Note that map is O(n), then sort O(n log n) and then index another O(n).
  • @Yevgeniy: If you pick small entry values you're doing non very interesting micro-benchmarkings. Try arr = [1,3,2,4]*10000 for example and you'll see the difference will be astronomical.
  • BTW, with_index isn't present in 1.8.7
  • How is the result [2, 1, 4, 3, 0] for the input array [8, 3, 2, 7, 5] wrong? a = [8,3,2,7,5] .. b = [a[2],a[1],a[4],a[3],a[0]] ..=> [2,3,5,7,8]
  • It would be helpful to the questioner if you explained what that snippet is doing, to avoid continuing the copy-paste-programming culture this site is so infamous for promoting