快速检索第一个字典值

时间:2018-09-11 14:38:10

标签: arrays swift dictionary

我有这种类型的字典:

var dict = [1: ["Value-1-1", "", ""],
            2: ["", "Value-2-2", "Value-2-3"], 
            3: ["Value-3-1", "Value-3-2", ""],
            4: ["Value-4-1", "", "Value-4-3"],
            5: ["", "", "Value-5-3"]]

我需要遍历该字典,并仅获取每个键下不为nil的第一个值并将其附加到数组中。

因此,最后,我的数组如下所示:

var array = ["Value-1-1", "Value-2-2", "Value3-1", "Value-4-1", "Value-5-3"]

我在这里已经读过这个问题-SO Question,但是它不包含空值,我想知道是否可以在没有map的情况下使用in或while循环?

如果有人可以提供这种循环的代码示例,将不胜感激。谢谢!

4 个答案:

答案 0 :(得分:4)

通过键对字典进行排序以获得明确的顺序, 这给出了键/值对的数组。 然后使用compactMap()first(where:)将每对映射到 值数组中的第一个非空字符串(如果存在):

let dict = [1: ["Value-1-1", "", ""],
            2: ["", "Value-2-2", "Value-2-3"],
            3: ["Value-3-1", "Value-3-2", ""],
            4: ["Value-4-1", "", "Value-4-3"],
            5: ["", "", "Value-5-3"]]


let array = dict.sorted(by: { $0.key < $1.key })
    .compactMap { $0.value.first(where: { !$0.isEmpty }) }

print(array) // ["Value-1-1", "Value-2-2", "Value-3-1", "Value-4-1", "Value-5-3"]

答案 1 :(得分:2)

这应该可以解决问题:
在学习编程时,这是一个好主意,它以算法方式使用手动循环而不是使用诸如map()之类的神奇方法。它们确实会循环,但它们是隐式的。
在这里,我使用了sorted()(因为它可能会有点长)。
我还使用了first(where:),它找到了第一个非空值。也可以用while循环替换它,但是我不知道您是否想要f​​or循环。

var dict = [1: ["Value-1-1", "", ""],
            2: ["", "Value-2-2", "Value-2-3"],
            3: ["Value-3-1", "Value-3-2", ""],
            4: ["Value-4-1", "", "Value-4-3"],
            5: ["", "", "Value-5-3"]]
var finalArray = [String]()
let keys = Array(dict.keys).sorted(by: { return $0<$1 }) // because keys aren't sorted
for aKey in keys {
    if let anArrayValue = dict[aKey], let firstNonEmptyValue = anArrayValue.first(where: { !$0.isEmpty }) {
        finalArray.append(firstNonEmptyValue)
    }
}
print("finalArray: \(finalArray)")

有关具有“更高级别”方法的版本,请参见@Martin R answer,但对于首次亮相者(链接,闭包等),其理解则更为复杂。它执行相同的操作,只是更紧凑,更不明确。

答案 2 :(得分:0)

这是我要解决的方法,但是它确实使用了flatMap:

var dict = [1: ["Value-1-1", "", ""],
            2: ["", "Value-2-2", "Value-2-3"],
            3: ["Value-3-1", "Value-3-2", ""],
            4: ["Value-4-1", "", "Value-4-3"],
            5: ["", "", "Value-5-3"]]

let newArray = dict.keys.flatMap({
    dict[$0]?.first(where: { !$0.isEmpty })
}).sorted()

print(newArray)

输出:

  

[“ Value-1-1”,“ Value-2-2”,“ Value-3-1”,“ Value-4-1”,“ Value-5-3”]

答案 3 :(得分:0)

这是一个不错的清晰管道,可以实现您想要的:

let dict = [1: ["Value-1-1", "", ""],
            2: ["", "Value-2-2", "Value-2-3"],
            3: ["Value-3-1", "Value-3-2", ""],
            4: ["Value-4-1", "", "Value-4-3"],
            5: ["", "", "Value-5-3"]]

let result = dict.values // we only care about values
    .compactMap { value in value.first(where: { !$0.isEmpty }) } // extract the first non-empty string, filter out nils (i.e. empty arrays or arrays made up only of empty strings
    .sorted() // sort the results
print(result) // ["Value-1-1", "Value-2-2", "Value-3-1", "Value-4-1", "Value-5-3"]

流水线的每个步骤,即使以简明的形式编写,也可以传达意图,从而更容易引起人们的共鸣。

我们可以对步骤2更加简洁:compactMap { $0.first { !$0.isEmpty } },IMO,这和上面的代码一样简洁,但是可能只是我的感觉。