2016-07-21 7 views
0

国とその国コードのリストのためのキー/値ペアを持つJSONファイルがあります。私はObjective-Cでそれを読んでいて、UIPickerにそれを提示したいと思います。 問題は、JSONデータをNSDictionaryに保存すると、元の順序が失われ、UIPicker要素の順序はかなり恣意的です(辞書には特定の順序がありません)。iOS - JSONオブジェクトを順序付けされた配列に変換する

元の注文を保存する最も簡単な方法は何ですか? 2つのファイルを作成する必要があります.1つは国コードで、もう1つは国名で同じ順序で作成し、両方を配列に読み込む必要がありますか? - 私は本当にしたいことを避ける...

[編集]要求ごととして

、JSON-データ(ローカルファイルに格納されている)の抜粋

{"af":"Afghanistan", 
    "al":"Albania", 
    "dz":"Algeria", 
    "as":"American Samoa", 
    "ad":"Andorra", 
    "ao":"Angola", 
    "ai":"Anguilla", 
    "aq":"Antarctica", 
    "ag":"Antigua and Barbuda", 
    "ar":"Argentina", 
    "am":"Armenia", 
    "aw":"Aruba", 
    "ac":"Ascension Island (Atlantic ocean)", 
    "au":"Australia", 
    "at":"Austria", 
    "az":"Azerbaijan", 
    "bs":"Bahamas", 
    "bh":"Bahrain", 
    "bd":"Bangladesh", 
    "bb":"Barbados", 
    "by":"Belarus", 
    "be":"Belgium", 
    "bz":"Belize", 
    "bj":"Benin", 
    "bm":"Bermuda", 
    "bt":"Bhutan", 
    "bo":"Bolivia", 
    "ba":"Bosnia", 
    "bw":"Botswana", 
    "bv":"Bouvet Island (Atlantic ocean)", 
    "br":"Brazil", 
    ... } 

[編集2]

私はJSONデータを読み込み、NSDictionaryに変換するためにこのコードを使用しています:

NSURL *jsonPath = [[NSBundle mainBundle] URLForResource:@"countries" withExtension:@"json"]; 
NSString *stringPath = [jsonPath absoluteString]; 

NSData *countriesJSON = [NSData dataWithContentsOfURL:[NSURL URLWithString:stringPath]]; 

NSDictionary *parsedJson = [NSJSONSerialization JSONObjectWithData:countriesJSON options:0 error:nil]; 
+0

あなたがデータを受信したJSON形式を共有してくださいすることができ –

+0

あなたのコードがNSDictionaryの – CokileCeoi

+2

にJSON配列を変換するために何が '元の順序に維持するための最も簡単な方法は何ですか? '辞書は順序付けられたコンテナではありません。元の注文というものはありません。注文したい場合は、まずそれを並べ替えてください。 – Desdenova

答えて

3

を行うことができますが、その後のようなコードを使用

[ 
{"af":"Afghanistan"}, 
{"al":"Albania"}, 
{"dz":"Algeria"}, 
{"as":"American Samoa"}, 
{"ad":"Andorra"}, 
{"ao":"Angola"}, 
{"ai":"Anguilla"}, 
... 
] 

にあなたのJSONデータを変更することができます。 countryArrayの要素はNSDictionaryインスタンスです。

+0

ありがとうCokile。スカンデルの提案のようなもの、まったく逆の; ...)私はあなたの提案を両方のショットに与えます。元のファイルを変更せずにそれを行う可能性がないことはあまりにも悪いです... – Swissdude

+0

@Swissdude OK。しかし、あなたのコードには問題があります。 'stringPath'を作成する必要はありません。ちょうど '[NSData dataWithContentsOfURL:jsonPath]'を使用してください – CokileCeoi

+0

ありがとう、もう一度、CokileCeoi。あなたのバージョンを使用しました。最も簡単な方法でした... - そして、stringPathのヒントのおかげで - 私はこれがどこから来たのか分かりませんでした(いくつかのウェブページからコピーしてください、私は推測します...) – Swissdude

1

順序が重要であり、あなたはJSONファイルへのアクセス権を持っている場合は、あなたがそうのような配列であるためにあなたのJSONを変更することができます:

[ 
    ["Afghanistan", "AF"], 
    ["Bangladesh", "BD"] 
] 

あなたがそれをデシリアライズするときのでその後、順序が保持されます逆シリアル化されたオブジェクトは配列の配列になります。

JSONファイルにアクセスできない場合は、コード内の辞書からこの配列の配列を作成できます。

編集

クイック検索や発注の両方が必要な場合、それは2つのデータ構造を使用しないように厳しいです。あなたは国の名前であるためにあなたのJSONファイル内の値の順序を切り替えるのが良いだろう、しかし

NSArray *countriesSorted = [parsedJson.allValues sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; 

:あなたが送信したJSONファイルで、あなたが、配列をしたいと思われる国コード。

NSURL *jsonPath = [[NSBundle mainBundle] URLForResource:@"sample" withExtension:@"json"]; 
NSData *countriesJSON = [NSData dataWithContentsOfURL:jsonPath]; 
NSMutableArray *countryArray = [NSJSONSerialization JSONObjectWithData: countriesJSON options:NSJSONReadingMutableContainers error:nil]; 

JSONがcountryArrayと呼ばれる規則的な配列に変換されます。そして、あなたは

NSArray *countryCodesSorted = [parsedJson.allKeys sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; 
NSString *firstCountryName = parsedJson[countryCodesSorted[0]]; 
+0

お返事ありがとうございます。 JSONファイルにアクセスできます。他に解決策がない場合は、私はあなたの提案を試してみましょう... – Swissdude

1

注文の問題と辞書は、辞書をテーブルビューで表示する必要がある場合によく発生します。このための確立された解決策は、ディクショナリの横に辞書キーの別々の配列を保持することです。あなた(またはユーザ)が好きなように配列を並べ替えることができ、配列を介して辞書エントリの2段階フェッチを実行できます。これにより、元のJSON形式と内部ストレージのプロパティ/インスタンス変数を保持することができます。

YourClass.m:

@interface MyClass() 
@property NSMutableArray *dictOrder; 
@end 

@implementation MyClass 

- (void)getData 
{ 
    self.dict = // Get dictonary from JSON 
    self.dictOrder = [[self.dict allKeys] mutableCopy]; 
    [self.dictOrder sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; 
} 


// UITableViewDataSource example 
- (UITableViewCell *)tableView:(UITableView *)tableView 
     cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    // Normal cell re-use stuff 
    NSString *key = self.dictOrder[indexPath.row]; 
    NSString *country = self.dict[key]; 
    // Populate cell 
} 

@end 
+0

ありがとうDroppy - 面白いアプローチ。私はCokileCeoiのソリューションと一緒に行きました。 – Swissdude

関連する問題