Skip to main content
provided a more detailed explanation for the code.
Source Link

To guarantee ascending order in both columns we can compare by column when there is no nil and by max value when there is:

.sort { |(a0, a1), (b0, b1)|
  a0, a1, b0, b1 = [a0, a1, b0, b1].map(&:to_i)

  if ![a0, b0].includenone?(0&:nil?)
    a0 <=> b0
  elsif ![a1, b1].includenone?(0&:nil?)
    a1 <=> b1
  else
    a0, a1, b0, b1 = [a0, a1, b0, b1].map(&:to_i)
    [[a0, a1].max, a0, a1] <=> [[b0, b1].max, b0, b1]
  end
}
  1. Compare two items at a time
  2. Convert all the nils to something we can work with (.to_i makes them zero).
  3. If the left columns are both positive integers then use that to sort.
  • this works because if they both have numbers then the right number is always correct relative to the left, so sorting on the left gets you the right result.
  1. If the right columns are both positive integers then use that to sort.
  1. If the right columns are both positive integers then use that to sort.
  • we know it's not a matched pair and both left numbers are nil and both rights are comparable so...
  1. Otherwise, create arrays to sort, with the 1st element of each array being the non-null (non-zero at this point) number. .max is just an easy way of getting the non-zero one.
  1. Convert all the nils to something we can work with (.to_i makes them zero).
  2. Otherwise, create arrays to sort, with the 1st element of each array being the non-null (non-zero at this point) number. .max is just an easy way of getting the non-zero one.

To guarantee ascending order in both columns we can compare by column when there is no nil and by max value when there is:

.sort { |(a0, a1), (b0, b1)|
  a0, a1, b0, b1 = [a0, a1, b0, b1].map(&:to_i)

  if ![a0, b0].include?(0)
    a0 <=> b0
  elsif ![a1, b1].include?(0)
    a1 <=> b1
  else
    [[a0, a1].max, a0, a1] <=> [[b0, b1].max, b0, b1]
  end
}
  1. Compare two items at a time
  2. Convert all the nils to something we can work with (.to_i makes them zero).
  3. If the left columns are both positive integers then use that to sort.
  • this works because if they both have numbers then the right number is always correct relative to the left, so sorting on the left gets you the right result.
  1. If the right columns are both positive integers then use that to sort.
  • we know it's not a matched pair and both left numbers are nil and both rights are comparable so...
  1. Otherwise, create arrays to sort, with the 1st element of each array being the non-null (non-zero at this point) number. .max is just an easy way of getting the non-zero one.

To guarantee ascending order in both columns we can compare by column when there is no nil and by max value when there is:

.sort { |(a0, a1), (b0, b1)|
  if [a0, b0].none?(&:nil?)
    a0 <=> b0
  elsif [a1, b1].none?(&:nil?)
    a1 <=> b1
  else
    a0, a1, b0, b1 = [a0, a1, b0, b1].map(&:to_i)
    [[a0, a1].max, a0, a1] <=> [[b0, b1].max, b0, b1]
  end
}
  1. Compare two items at a time
  2. If the left columns are both positive integers then use that to sort.
  • this works because if they both have numbers then the right number is always correct relative to the left, so sorting on the left gets you the right result.
  1. If the right columns are both positive integers then use that to sort.
  • we know it's not a matched pair and both left numbers are nil and both rights are comparable so...
  1. Convert all the nils to something we can work with (.to_i makes them zero).
  2. Otherwise, create arrays to sort, with the 1st element of each array being the non-null (non-zero at this point) number. .max is just an easy way of getting the non-zero one.

To guarantee ascending order in both columns we can compare by column when there is no nil and by max value when there is:

.sort { |(a0, a1), (b0, b1)|
  a0, a1, b0, b1 = [a0, a1, b0, b1].map(&:to_i)

  if ![a0, b0].include?(0)
    a0 <=> b0
  elsif ![a1, b1].include?(0)
    a1 <=> b1
  else
    [[a0, a1].max, a0, a1] <=> [[b0, b1].max, b0, b1]
  end
}
  1. Compare two items at a time
  2. Convert all the nils to something we can work with (.to_i makes them zero).
  3. If the left columns are both positive integers then use that to sort.
  • this works because if they both have numbers then the right number is always correct relative to the left, so sorting on the left gets you the right result.
  1. If the right columns are both positive integers then use that to sort.
  • we know it's not a matched pair and both left numbers are nil and both rights are comparable so...
  1. Otherwise, create arrays to sort, with the 1st element of each array being the non-null (non-zero at this point) number. .max is just an easy way of getting the non-zero one.

To guarantee ascending order in both columns we can compare by column when there is no nil and by max value when there is:

.sort { |(a0, a1), (b0, b1)|
  a0, a1, b0, b1 = [a0, a1, b0, b1].map(&:to_i)

  if ![a0, b0].include?(0)
    a0 <=> b0
  elsif ![a1, b1].include?(0)
    a1 <=> b1
  else
    [[a0, a1].max, a0, a1] <=> [[b0, b1].max, b0, b1]
  end
}

To guarantee ascending order in both columns we can compare by column when there is no nil and by max value when there is:

.sort { |(a0, a1), (b0, b1)|
  a0, a1, b0, b1 = [a0, a1, b0, b1].map(&:to_i)

  if ![a0, b0].include?(0)
    a0 <=> b0
  elsif ![a1, b1].include?(0)
    a1 <=> b1
  else
    [[a0, a1].max, a0, a1] <=> [[b0, b1].max, b0, b1]
  end
}
  1. Compare two items at a time
  2. Convert all the nils to something we can work with (.to_i makes them zero).
  3. If the left columns are both positive integers then use that to sort.
  • this works because if they both have numbers then the right number is always correct relative to the left, so sorting on the left gets you the right result.
  1. If the right columns are both positive integers then use that to sort.
  • we know it's not a matched pair and both left numbers are nil and both rights are comparable so...
  1. Otherwise, create arrays to sort, with the 1st element of each array being the non-null (non-zero at this point) number. .max is just an easy way of getting the non-zero one.
added 37 characters in body
Source Link

EditedTo guarantee ascending order in both columns we can compare by column when there is no nil and by max value when there is:

src.sort_bysort { |_0|(a0, _1|a1), _0i(b0, _1ib1)|
  a0, a1, b0, b1 = [_0[a0, _1]a1, b0, b1].map(&:to_i); 

 [[_0 if ![a0, _1]b0].include?(nil0) ? [_0i, _1i].max 
 : [_0i, _1i].min, _0i,a0 _1i]<=> }b0
=> [[nil, 1], [1, 2], [2, nil],elsif [nil![a1, 3],b1].include?(0)
 [3, nil], [nil, 4],a1 [4,<=> nil],b1
 [nil, 5],else
 [5, nil], [nil, 6][[a0, [6a1].max, 8]a0, [nil,a1] 7],<=> [7[[b0, 9]b1].max, [8b0, nil],b1]
 [9, 10]]end
}

The trick is to use min when both are Numeric, max when there's a nil

Edited:

src.sort_by { |_0, _1| _0i, _1i = [_0, _1].map(&:to_i); [[_0, _1].include?(nil) ? [_0i, _1i].max : [_0i, _1i].min, _0i, _1i] }
=> [[nil, 1], [1, 2], [2, nil], [nil, 3], [3, nil], [nil, 4], [4, nil], [nil, 5], [5, nil], [nil, 6], [6, 8], [nil, 7], [7, 9], [8, nil], [9, 10]]

The trick is to use min when both are Numeric, max when there's a nil

To guarantee ascending order in both columns we can compare by column when there is no nil and by max value when there is:

.sort { |(a0, a1), (b0, b1)|
  a0, a1, b0, b1 = [a0, a1, b0, b1].map(&:to_i) 

  if ![a0, b0].include?(0) 
    a0 <=> b0
  elsif ![a1, b1].include?(0)
    a1 <=> b1
  else
    [[a0, a1].max, a0, a1] <=> [[b0, b1].max, b0, b1]
  end
}
added 98 characters in body
Source Link
Loading
Source Link
Loading