2017-07-06 12 views
-1

これについては、最も効率的な方法を探しています。オブジェクトの配列があると言って、名前のアルファベット順にマッピングされた:スプリットとソートの文字列配列のスウィフト3

let objectArray = [AnyObject]() 
let abcNameObjectArray = ["Amy", "Bernadette", "Brian", "Chris", "Candice"] 

を私が最初に基づいて、「A」、「B」、または「C」を持って、この配列内のすべての値にアクセスする方法abcNameObject配列の各文字列値の文字(アルファベット順)?私は、データをアンロードしようとすると、アルファベット順に持っている可能性のある友人の数に基づいて、UITableViewのcellForRowAtメソッドとnumberOfRowsInSectionメソッドで特定の数の行を返します。 目的は、アレイを一連の配列に分割して、連絡先アプリのようなテーブルビューを作成し、特定のセクションの値にアクセスすることです。多分辞書を利用する方がこれを解決する方がいいでしょうか?

+1

[配列のアルファベット順のソート](https:// stackoverflow。com/questions/36394813 /アルファベット順のアルファベット順) –

+0

既にソートされている場合、何をしようとしていますか?なぜあなたは配列全体を反復して、 "A"というキーとメンバーの配列としての値を持つ辞書の配列を作成しませんか?ここで並べ替えるものはありません。あなたが見つけた順番で辞書内のこの配列に要素を追加し続けるだけです。 – adev

+0

質問を入力して、希望する結果で質問を編集する必要があります。あなたがここで期待していることは明確ではありません。 – rmaddy

答えて

1

解決方法1:

コードとの答えとして私のコメントを投稿。これがあなたのために働くかどうか確認してください。下に印刷された最初の配列のセクションを使用して(一部の配列にdict.keys.sorted()を格納)、それをそのセクションのセルを表示するためのキーとして使用できます。

let abcNameObjectArray = ["Amy", "Bernadette", "Brian", "Chris", "Candice", ""] 

let dict = abcNameObjectArray.reduce([String: [String]]()) { (key, value) -> [String: [String]] in 
    var key = key 
    if let first = value.characters.first { 
     let prefix = String(describing: first).lowercased() 
     var array = key[prefix] 

     if array == nil { 
      array = [] 
     } 
     array!.append(value) 
     key[prefix] = array!.sorted() 
    } 
    return key 
} 

print(dict.keys.sorted()) 
print(dict) 

出力:

[ "A"、 "B"、 "C"]

[ "B":[ "ベルナデット"、 "ブライアン"] "" :[ "エイミー"]、 "C":[ "キャンディス"、 "クリスは"]]

解決策2:ここ

が1メートルであります

[[ "エイミー"]、[ "ベルナデット"、 "ブライアン"]、[ "クリス"、 "キャンディス":rmaddy

let abcNameObjectArray = ["Amy", "Bernadette", "Brian", "Chris", "Candice", ""] 
let unicodeScalarA = UnicodeScalar("a")! 

var arrayOfArrays = abcNameObjectArray.reduce([[String]]()) { (output, value) -> [[String]] in 
    var output = output 

    if output.count < 26 { 
     output = (1..<27).map{ _ in return []} 
    } 

    if let first = value.characters.first { 
     let prefix = String(describing: first).lowercased() 
     let prefixIndex = Int(UnicodeScalar(prefix)!.value - unicodeScalarA.value) 
     var array = output[prefixIndex] 
     array.append(value) 
     output[prefixIndex] = array.sorted() 
    } 
    return output 
} 

arrayOfArrays = arrayOfArrays.filter { $0.count > 0} 
print(arrayOfArrays) 

出力により示唆されるように鉱石ソリューション配列の配列を使用して]]

このアレイのカウントとしてセクション数を指定でき、各メンバーはそのセクションで必要なセル数を指定できます。

+0

申し訳ありませんが返答できませんでしたが、あなたのソリューションはまだ最高のものだと思いますので、これを答えにします。しかし、文字列の配列ではなく、オブジェクトの配列を返すように出力を変更する方法はありますか? –

+0

お受け取りいただきありがとうございます。はい、何かを返すことができます。これは単なる例です。上記のようにreduceメソッドを変更し、オブジェクトの配列を返すようにすることができます。試してみることができない場合は、お気軽に質問してください。我々はあなたを助けることができる。 – adev

0

Setは、テーブルビューのデータソースとしては適していません。 Dictionaryも良い選択ではありません。両方とも順序付けされていないコレクションであり、テーブルビューのデータソースには明確な順序が必要です。ソース配列を配列の配列に分割することをお勧めします。各配列には、アルファベット順にソートされた特定の文字で始まるすべての単語が含まれています。コードは、それは次のようになりますか:あなたはすべての文字のエントリを持つ配列をしたい場合はそので始まる言葉が存在しない場合でも、

["Aces", "Achy-breaky heart", "Acorn", "apple", "arf"] 
["baseballs"] 
["Cards"] 
["Dogs"] 
["flounder"] 
["Manbaby"] 
["songbirds", "Suet"] 
["Tiny-fingered, cheeto-faced, ferret-wearing sh*tgibbon"] 
["woofing"] 

:次のような出力が得

import UIKit 

let strings = ["arf", 
       "woofing", 
       "flounder", 
       "Manbaby", 
       "Dogs", 
       "baseballs", 
       "Suet", 
       "Cards", 
       "Tiny-fingered, cheeto-faced, ferret-wearing sh*tgibbon", 
       "apple", 
       "Acorn", 
       "Achy-breaky heart", 
       "songbirds", 
       "Aces"] 

let aValue = "a".unicodeScalars.first!.value 
let zValue = "z".unicodeScalars.first!.value 


var result = [[String]]() 
for value in aValue...zValue { 
    let aChar = Character(UnicodeScalar(value)!) 
    let thisArray = strings 
    .filter{$0.lowercased().characters.first! == aChar} 
    .sorted{$0.caseInsensitiveCompare($1) == .orderedAscending} 
    if !thisArray.isEmpty { 
    result.append(thisArray) 
    } 
} 

result.forEach{print($0)} 

if !thisArray.isEmpty試験を取り除く。

関連する問題