2

I have to sort this

ary = [[5, "e", "2"], [2, "r", "="], [2, "y", "2"], [2, "h", "="]]

to obtain :

# => [[5, "e", "2"], [2, "y", "2"], [2, "h", "="], [2, "r", "="]] 

If the last element (index 2) is equal to "=" it must be after the array which has the same first element even if the letter is before. Something like this :

ary.each_with_index do |array, index|
  if ary[index][2] == "=" && ary[index][0] == ary[index +1][2]
    a = ary[index]
    b = ary[index +1]
    ary[index] = b
    ary[index+1] = a
  end
end
1
  • Looking at the elements with "=", do you want to sort in decreasing order on the first element? When there are ties, sort in increasing order of the second element? Same for elements without "="? What aboutary = [[2, "e", "2"], [2, "e", "10"]]? Please clarify by editing (rather than posting a comment). Commented Sep 28, 2017 at 20:31

2 Answers 2

2

I assume that, for elements ending with "=", sorting is by decreasing value of the first element (integers) and when there are ties, by increasing order of the second element (strings). Further, I assume sorting is the same for elements not ending with "=", except when the first two elements both tie, sorting is by increasing order of the last element (strings).

def sort_em(arr)
  arr.sort_by { |n, s1, s2| [s2 == "=" ? 1 : 0, -n, s1, s2] }
end

sort_em [[5, "e", "2"], [2, "r", "="], [2, "y", "2"], [2, "h", "="]]
  #=> [[5, "e", "2"], [2, "y", "2"], [2, "h", "="], [2, "r", "="]]

See the third paragraph of the doc for Array#<=> for an explanation of how arrays are ordered when sorting.

To ensure elements ending with "=" come last in the sort, I've simply added 1 (0) at the beginning of array in sort_by's block for arrays ending (not ending) with "=".

Sign up to request clarification or add additional context in comments.

Comments

1

You can use sort and provide your own block for sorting:

ary.sort do |a, b| 
  if a[2] == '=' && b[2] != '='
    # a has '=' => a > b 
    1
  elsif b[2] == '=' && a[2] != '='
    # b has '=' => a < b 
    -1
  else
    # This is hit if neither a nor b have a '=' OR when both do.
    # Use default comparison operator
    # but restrict it to the second element of the array
    a[1] <=> b[1]
  end
end

The block needs to return a value that is 1, -1 or 0. Based on this, the values are placed in order.

  • 1: a > b
  • -1: a < b
  • 0: a = b

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.