2016-11-24 4 views
0

私は一般にSwiftとプログラミングに慣れています。私はdictionary次宣言している:文字列をキーとし、Anyの配列を値として辞書の内容にアクセスするには?

let fruits: [String:[[Any]]] = [ 
    "Apple": [ 
     ["Gravenstein",122,100], 
     ["Ginger Gold", 119, 130], 
     ["Jazz", 150, 190] 

    ], 

    "Grapes": [ 
     ["Cabernet Sauvignon",120,100], 
     ["Merlot", 150, 130], 
     ["Tempranillo", 130, 190] 

    ] 
] 

私は2つの変数、たとえば、var selectedFruit = "Apple"var selectedVariety = "Ginger Gold"に基づいて、今その機能をプログラミングしたいです。これらの2つの変数に基づいて、最初の数値(122)を取得して2番目の数値(100)に追加できるはずです。私はmapとflatmapを試してみましたが、成功しませんでした。どんな助け?このような

+0

あなたがこれまでにしてくださいしようとしているものを私たちに示しています。 – dirtydanee

+0

配列(true、false)を返すprint(fruits.map {$ 0.key == selectedFruit})がありましたが、ここで私は固まってしまいました.... – fbelfort

答えて

2

何かが、あなたが取得します:

let selectedFruit = "Apple" 
let selectedVariety = "Ginger Gold" 

if let arrays = fruits[selectedFruit] { 
    for array in arrays { 
     if let first = array.first as? String, first == selectedVariety { 
      if let num1 = array[1] as? Int, let num2 = array[2] as? Int { 
       print(num1 + num2) 
      } 
     } 
    } 
} 

しかし、あなたはほぼ確実にあなたのデータのための間違った構造を選択しました。あなた自身がAnyを使用していると分かった場合は、より良い解決策があります。

最も簡単なことは、あなたのフルーツと品種をキーにしてネストされた辞書を持つことです。

let fruits: [String: [String: [Int]]] = [ 
    "Apple": [ 
     "Gravenstein": [122, 100], 
     "Ginger Gold": [119, 130], 
     "Jazz": [150, 190] 
    ], 

    "Grapes": [ 
     "Cabernet Sauvignon": [120, 100], 
     "Merlot": [150, 130], 
     "Tempranillo": [130, 190] 
    ] 
] 

if let values = fruits[selectedFruit]?[selectedVariety] { 
    print(values[0] + values[1]) 
} 
+0

答えをありがとう。したがって、新しい構造体は、文字列をキーとし、辞書の配列を値として持つ辞書です。私はそれを得る。 "?"の目的は何ですか? [selectedFruit]と[selectedVariety]の間にありますか? – fbelfort

+0

新しい構造体は、文字列をキーとし、文字列をキーとし、辞書の値としてIntsの配列を持つ辞書である辞書です。ディクショナリルックアップは、キーが存在しない可能性があるため、常にオプションの結果を返します。あなたはそれを使用するために結果をアンラップする必要があります。この場合の '?'は* optional chaining *と呼ばれ、 'nil'でなければ最初の辞書検索をアンラップして2番目の辞書検索を進めることができます。いずれかのルックアップが 'nil'を返すと、*オプションのチェーン*の結果は' nil'になり、 'if let'は起こりません。いずれにせよ、これは完全に安全です。 – vacawama

3

まず、辞書が少し構成される方法を変更します。配列の配列を持つ代わりに、配列を辞書の配列に変更します。したがって、次のようなもの:

func getTotalValue(fruitName: String, varietyName: String) -> Int? { 

    guard let varieties = fruits[fruitName] else { return nil } 
    guard let values = varieties[varietyName] else { return nil } 

    return values.reduce(0, +) 
} 

そしてそうのようにそれを使用する:あなたは、単にこのようなメソッドを書くことができることを行っているたら

let fruits: [String:[String: [Int]]] = [ 
    "Apple": [ 
     "Gravenstein": [122,100], 
     "Ginger Gold": [119, 130], 
     "Jazz": [150, 190] 

    ], 

    "Grapes": [ 
     "Cabernet Sauvignon": [120,100], 
     "Merlot": [150, 130], 
     "Tempranillo": [130, 190] 

    ] 
] 

ここ

getTotalValue(fruitName: "Apple", varietyName: "Gravenstein") 
0

ですあなたの果物を見つける機能。私もコメントを追加しましたので、簡単に検索できるようにコンテナを変更することができます。

// it is enough to say your container is [String: Any] 
    let fruits: [String: Any] = [ 
     "Apple": [ 
      ["Gravenstein",122,100], 
      ["Ginger Gold", 119, 130], 
      ["Jazz", 150, 190] 

     ], 


    "Grapes": [ 
     ["Cabernet Sauvignon",120,100], 
     ["Merlot", 150, 130], 
     ["Tempranillo", 130, 190] 

    ] 
] 

func findFruits(name: String, type: String) -> (Int, Int)? { 
    // Declare nil tuple 
    var searchedFruitValues: (Int, Int)? 
    // First lets see if we have the fruit in the container 
    if let fruit = fruits[name] as? [[Any]]{ 
     // Iterate through every element 
     fruit.forEach({ (element) in 
      // If the first element is equal to the searched type, check the numbers 
      if type == (element.first as? String) { 
       // If they are integers, lets associate the value to searchedFruitValues 
       if let first = element[1] as? Int, let second = element[2] as? Int { 
        searchedFruitValues = (first, second) 
       } 
      } 
     }) 
    } 
    // Return nil or the found values 
    return searchedFruitValues 
} 

let searched = findFruits(name: "Apple", type: "Jazz") 
print(searched ?? "not found") 
0

別の解決策:

struct Fruit { 
    var name : String 
    var variety : [Variety] 
} 

struct Variety { 
    var name : String 
    var numbers : [Int] 

    func getNumbers() -> Int { 
     var result = 0 
     for value in self.numbers { 
      result += value 
     } 
     return result 
    } 
} 

//example data 
let apples = [ 
    Variety(name: "Gravenstein", numbers: [122, 100]), 
    Variety(name: "Ginger Gold", numbers: [119, 130]) 
] 

let grapes = [ 
    Variety(name: "Cabernet Sauvignon", numbers: [120,100]), 
    Variety(name: "Merlot", numbers: [150, 130]) 
] 


let fruits = [ 
    Fruit(name: "Apple", variety: apples), 
    Fruit(name: "Garpes", variety: grapes) 
] 

//the actual call for the Variety numbers 
    if let goldenGinger = fruits.first(where: { $0.name == "Apple"})?.variety.first(where: { $0.name == "Ginger Gold"}) { 
     print(goldenGinger.getNumbers()) 
    } 
関連する問題