我有这种类型的字典:
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循环?
如果有人可以提供这种循环的代码示例,将不胜感激。谢谢!
答案 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循环替换它,但是我不知道您是否想要for循环。
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,这和上面的代码一样简洁,但是可能只是我的感觉。