2016-04-08 21 views
4

私のAndroidアプリケーションでは、1,2,3の順序でバスルートタグをソートしようとしています。そのために文字と長さで文字列を並べ替える

私は5

、私が午前問題はこれがそれらをソートしているこの

Collections.sort(directions, Comparator { lhs, rhs -> 
     var obj1 = lhs.short_names.firstOrNull() ?: "" 
     var obj2 = rhs.short_names.firstOrNull() ?: "" 

     if (obj1 === obj2) { 
      obj1 = lhs.headsigns.firstOrNull() ?: "" 
      obj2 = rhs.headsigns.firstOrNull() ?: "" 
      if (obj1 === obj2) { 
       [email protected] 0 
      } 
      obj1.compareTo(obj2) 
     } else { 
      obj1.compareTo(obj2) 
     } 

を使用していますが、 1、2、3、30、31、4の問題に実行されます

正しい注文を得るには、これをどのように変更する必要がありますか?

答えて

4

単純な数値比較が必要な場合は、そのようにすることができます。 hotkeyとして

directions.sortWith(Comparator { lhs, rhs -> 
    val i1 = lhs.toInt() 
    val i2 = rhs.toInt() 
    when { 
    i1 < i2 -> -1 
    i1 > i2 -> 1 
    else -> 0 
    } 
}) 

上記のコードはあまりsimplierに見えるほぼ同じ実装に置き換えることができます指摘。

directions.sortBy { it.toInt() } 

このアルゴリズムの一般的なバージョンは、ソーティングalphanumと呼ばれ、詳細hereに記載されています。私はあなたが使用できるこのアルゴリズムのKotlinポートを作った。必要以上に複雑ですが、問題が解決します。あなたはあなただけDave Koelle's pageに元のJavaのバージョンを取ることができ、それがKotlinでコーディングする必要がない場合は

class AlphanumComparator : Comparator<String> { 
    override fun compare(s1: String, s2: String): Int { 
    var thisMarker = 0 
    var thatMarker = 0 
    val s1Length = s1.length 
    val s2Length = s2.length 

    while (thisMarker < s1Length && thatMarker < s2Length) { 
     val thisChunk = getChunk(s1, s1Length, thisMarker) 
     thisMarker += thisChunk.length 

     val thatChunk = getChunk(s2, s2Length, thatMarker) 
     thatMarker += thatChunk.length 

     // If both chunks contain numeric characters, sort them numerically. 
     var result: Int 
     if (isDigit(thisChunk[0]) && isDigit(thatChunk[0])) { 
     // Simple chunk comparison by length. 
     val thisChunkLength = thisChunk.length 
     result = thisChunkLength - thatChunk.length 
     // If equal, the first different number counts. 
     if (result == 0) { 
      for (i in 0..thisChunkLength - 1) { 
      result = thisChunk[i] - thatChunk[i] 
      if (result != 0) { 
       return result 
      } 
      } 
     } 
     } else { 
     result = thisChunk.compareTo(thatChunk) 
     } 

     if (result != 0) { 
     return result 
     } 
    } 

    return s1Length - s2Length 
    } 

    private fun getChunk(string: String, length: Int, marker: Int): String { 
    var current = marker 
    val chunk = StringBuilder() 
    var c = string[current] 
    chunk.append(c) 
    current++ 
    if (isDigit(c)) { 
     while (current < length) { 
     c = string[current] 
     if (!isDigit(c)) { 
      break 
     } 
     chunk.append(c) 
     current++ 
     } 
    } else { 
     while (current < length) { 
     c = string[current] 
     if (isDigit(c)) { 
      break 
     } 
     chunk.append(c) 
     current++ 
     } 
    } 
    return chunk.toString() 
    } 

    private fun isDigit(ch: Char): Boolean { 
    return '0' <= ch && ch <= '9' 
    } 
} 

が、これは Comparatorだけ

directions.sortWith(AlphanumComparator()) 

を呼び出して使用します。アルゴリズムのKotlinバージョンはGitHubにもあります。

+1

'toInt()'の最初の解決策は 'a.sortBy {it.toInt()}'に書き直すことができます。 – hotkey

+0

@Michaelが、私はそれを実装するとやや混乱しています(kotlinすることは非常に新しい)私は、私が使用する必要があり、それを呼び出すために今kotlinポート を追加 Collections.sort(directions.sortWith(AlphanumComparator()) か? –

+0

わずかに異なる何か@AnthonyTaylor 'Collections.sort()'は必要ありません。 'directions.sortWith(AlphanumComparator())'を呼び出してください。 – Michael

関連する問題