2

I changed how I was doing things but at one point I needed to append a string to the end of an array of strings and I wanted it guaranteed to be lexicologically after all of the other strings. For integers this would be MAXINT or some similar constant.

In my particular case, I'm using Ruby. I want some Ω such that "Ω" > "s" for all s.

SuperStormer
  • 4,997
  • 5
  • 25
  • 35
pedz
  • 2,271
  • 1
  • 17
  • 20
  • 1
    Suppose the array were `["dog", "pig", "rat"]`. Adding the string "cat" would work, provided you work with the array `[[0, "dog"], [0, "pig"], [0, "rat"], [1, "cat"]]`. This has the property that if `s` and `t` both equal `"dog"`, `"pig"` or `"rat"`, then `(s<=>t) == ([0, s]<=>[0, t]) #=> true` and `[0, s]<=>[1, "cat"] == -1 #=> true`. In other words, the lexicographic ordering of the original elements in the array is the same as that of the array of 2-element arrays and `[0, s]` (`s` from the original array) will always precede `[1, "cat"]` in lexicographic ordering. – Cary Swoveland Apr 18 '22 at 07:09
  • 1
    The lexicographic ordering between strings depends on the locale, in particular on the LC_COLLATE property. I'm not sure whether you can do a sorting based on the Unicode code point value (maybe exporting LC_COLLATE=C can do this). In this case, you may want to look at [this](https://stackoverflow.com/questions/27415935/does-unicode-have-a-defined-maximum-number-of-code-points) thread. – user1934428 Apr 19 '22 at 07:44
  • 1
    May I ask why you need an arbitrary "maximum" string at the end of your array? Smells like an XY problem :-) – Stefan Apr 19 '22 at 08:20
  • @Stefan I don't know what an XY problem is. I am going through two lists: one is a list of children from the real file system directory. The other is the list of children from a DB that is suppose to match the file system. I sort the lists, then go through the lists at the same time. If fs == db, its the same child. if fs < db, then a is new file has been added. If db < fs then db has a child that has been removed. – pedz Apr 19 '22 at 11:59
  • @pedz okay, but why do you need that fake entry at the list's end? – Stefan Apr 19 '22 at 12:07
  • Ahh... an XY problem. Yes, this question is not trying to solve my coding problem -- as I stated, I had already solved it by another approach. This question is sort of a curiosity type question more than a practical "how do I solve my pain point" question. I may have been better suited in another SE board but I didn't see one. – pedz Apr 19 '22 at 12:09
  • @Stefan I made the array an iterator and I didn't want to go off the end, catch the exception and put a dummy value. Rather, just put a dummy value at the end of the iterator. The other choice is special case if one list goes empty first, finish off the other list in its own separate loop. Both of which are more complicated. I ended up just adding a nil at the end and adding slightly ugly (foo && foo.child ... ) stuff. – pedz Apr 19 '22 at 12:12

1 Answers1

4

There's no such string satisfying that behavior. Such a string would have to be an infinite sequence of the largest Unicode codepoint, and strings in Ruby cannot be infinite.

However, we can always make a class for which we control the comparison operator.

class OmegaType

  include Comparable

  def <=>(other)
    if other.is_a? OmegaType
      0
    else
      1
    end
  end

end

Omega = OmegaType.new

And then, if we really want to, we can monkeypatch String to agree with our assessment.

class String

  alias old_cmp <=>

  def <=>(other)
    if other.is_a? OmegaType
      -1
    else
      self.old_cmp other
    end
  end

end

Now, we find

puts(Omega > 'a') # true
puts('a' < Omega) # true

But is this good practice? Not really. It's probably best to go through whatever list of strings your actual program uses and just pick the "maximum" string to be your "after" value. Or pick something that works in your use case. For instance, if all the strings you're dealing with are alphanumeric, then pick a Unicode character larger than all alphanumerics.

Silvio Mayolo
  • 62,821
  • 6
  • 74
  • 116