How do string intervals work?

廉价感情. 提交于 2019-12-07 04:17:12

问题


I did some playing around in this answer, and have even raised a RADAR issue with Apple, asking for better documentation on the matter (Crickets chirping).

The question is this: How do String Intervals work?

If you look at line 367 in my playground, you'll see me messing with String Intervals.

I extracted the String stuff into a smaller playground:

// String Intervals
// These are odd. Looks like it is using the ASCII values. I should experiment with Unicode, and see where we go...
let aThroughFClosed:ClosedInterval<String>          = "A"..."F"
let dThroughQClosed:ClosedInterval                  = "D"..."Q"
let mThroughSClosed:ClosedInterval                  = "M"..."S"
let tThroughWClosed:ClosedInterval                  = "T"..."W"
let whiskeyTangoFoxtrot1                            = "QED"..."WTF" /* Not sure what will happen when I start working with this... */
let aThroughHHalfOpen:HalfOpenInterval<String>      = "A"..<"H"
let dThroughRHalfOpen:HalfOpenInterval              = "D"..<"R"
let mThroughTHalfOpen:HalfOpenInterval              = "M"..<"T"
let tThroughXHalfOpen:HalfOpenInterval              = "T"..<"X"
let whiskeyTangoFoxtrot2                            = "QED"..<"WTF"
let clampedString1 = aThroughFClosed.clamp ( dThroughQClosed )  /* This represents "D"..."F" */
let clampedString2 = dThroughQClosed.clamp ( aThroughFClosed )  /* This represents "D"..."F" */
let clampedString3 = dThroughQClosed.clamp ( mThroughSClosed )  /* This represents "M"..."Q" */
let clampedString4 = dThroughQClosed.clamp ( tThroughWClosed )  /* This represents "Q"..."Q" */
let clampedString5 = aThroughFClosed.clamp ( tThroughWClosed )  /* This represents "F"..."F" */
let clampedString6 = aThroughHHalfOpen.clamp ( dThroughRHalfOpen )  /* This represents "D"..<"G" */
let clampedString7 = dThroughRHalfOpen.clamp ( aThroughHHalfOpen )  /* This represents "D"..<"H" */
let clampedString8 = dThroughRHalfOpen.clamp ( mThroughTHalfOpen )  /* This represents "M"..<"R" */
let clampedString9 = dThroughRHalfOpen.clamp ( tThroughXHalfOpen )  /* This represents "R"..<"R" */
let clampedString0 = aThroughHHalfOpen.clamp ( tThroughXHalfOpen )  /* This represents "H"..<"H" (Not exactly sure why) */

// 2.2.3: STRING INTERVALS

// String intervals are weird. Just sayin'...

// 2.2.3.1: STRING INTERVALS AS SWITCH TESTS

var testValue3:String = "B"

switch ( testValue3 )
    {
case aThroughFClosed:   /* This will catch it. */
    println ( "In A...F." )

default:
    println ( "In catchall." )
}

// Looks like the test is only on the first letter.
testValue3 = "Badz-Maru"

switch ( testValue3 )
    {
case aThroughFClosed:   /* This will catch it. */
    println ( "In A...F." )

default:
    println ( "In catchall." )
}

testValue3 = "\tBadz-Maru"   /* If we add a tab character to the start of the string, then the first test will fail. */

switch ( testValue3 )
    {
case aThroughFClosed:
    println ( "In A...F." )

default:    /* This will catch it. */
    println ( "In catchall." )
}

// Now, we'll get really strange. Let's look at our multi-character intervals...

testValue3 = "W"

switch ( testValue3 )
    {
case whiskeyTangoFoxtrot2:  /* This catches it. */
    println ( "WTF, dude?" )

default:
    println ( "In catchall." )
}

testValue3 = "T"

switch ( testValue3 )
    {
case whiskeyTangoFoxtrot2:  /* This catches it. */
    println ( "WTF, dude?" )

default:
    println ( "In catchall." )
}

testValue3 = "F"

switch ( testValue3 )
    {
case whiskeyTangoFoxtrot2:
    println ( "WTF, dude?" )

default: /* However, in this case, it falls through to default. */
    println ( "In catchall." )
}

testValue3 = "WT"

switch ( testValue3 )
    {
case whiskeyTangoFoxtrot2: /* "WT" is caught. */
    println ( "WTF, dude?" )

default:
    println ( "In catchall." )
}

testValue3 = "WTF"

switch ( testValue3 )
    {
case whiskeyTangoFoxtrot2:
    println ( "WTF, dude?" )

default:    /* "WTF" is not caught. */
    println ( "In catchall." )
}

testValue3 = "QED"

switch ( testValue3 )
    {
case whiskeyTangoFoxtrot2:  /* "QED" is caught. */
    println ( "WTF, dude?" )

default:
    println ( "In catchall." )
}

testValue3 = "QTF"

switch ( testValue3 )
    {
case whiskeyTangoFoxtrot2:  /* "QTF" is caught. */
    println ( "WTF, dude?" )

default:
    println ( "In catchall." )
}

testValue3 = "QSF"

switch ( testValue3 )
    {
case whiskeyTangoFoxtrot2:  /* "QSF" is caught. */
    println ( "WTF, dude?" )

default:
    println ( "In catchall." )
}

testValue3 = "QAF"

switch ( testValue3 )
    {
case whiskeyTangoFoxtrot2:
    println ( "WTF, dude?" )

default: /* QAF falls through. */
    println ( "In catchall." )
}

回答1:


As I understand it, ClosedInterval(lo, hi) represents all strings s such that

lo <= s <= hi

and HalfOpenInterval(lo, hi) represents all strings s such that

lo <= s < hi

where <= and < are determined by the lexicographic ordering of the Strings, i.e. be comparing the characters one by one, until a difference is found.

For example "QED" < "T" < "WTF" because Q < T < W, but "F" < "QED" because F < Q. Therefore

HalfOpenInterval("QED" , "WTF").contains("T") == true
HalfOpenInterval("QED" , "WTF").contains("F") == false

And "QED" < "QSF" because Q == Q and E < S, but "QAF" < "QED" because Q == Q and A < E. Therefore

HalfOpenInterval("QED" , "WTF").contains("QSF") == true
HalfOpenInterval("QED" , "WTF").contains("QAF") == false

That should explain all your test results.

Finally,

let clampedString0 = aThroughHHalfOpen.clamp ( tThroughXHalfOpen )

is an empty interval because "A"..<"H" and "T"..<"X" have no points in common. An empty interval can be represented by HalfOpenInterval(dummy, dummy) for any value of dummy.



来源:https://stackoverflow.com/questions/25711222/how-do-string-intervals-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!