简体   繁体   English

如何遍历可选集合

[英]How to loop through an optional collection

What's the Swifty way to unwrap an optional collection directly before a loop?在循环之前直接打开可选集合的Swifty方法是什么? Consider the following:考虑以下:

let elements: [Element]?
for element in elements { ... }

where elements may contain values.其中elements可能包含值。 The compiler produces the error: For-in loop requires '[Element]?' to conform to 'Sequence'; did you mean to unwrap optional?编译器产生错误: For-in loop requires '[Element]?' to conform to 'Sequence'; did you mean to unwrap optional? For-in loop requires '[Element]?' to conform to 'Sequence'; did you mean to unwrap optional? , similarly with forEach . ,与forEach类似。

Using the where -Keyword to tell the compiler that I only want to iterate if there are values in elements like this使用where -Keyword 告诉编译器我只想迭代这样的elements是否有值

for element in elements where elements != nil { ... }

does not work.不起作用。 I am basically looking for a way to unwrap the collection where I don't have to write verbose guard let or if let before iterating through the loop.我基本上是在寻找一种解包集合的方法,我不必在遍历循环之前编写冗长的guard letif let

I am not looking to extend Sequence with a property that returns unwrapped self , I just don't think it's very elegant (including force-unwrapping).我不希望使用返回解包self的属性来扩展Sequence ,我只是认为它不是很优雅(包括强制解包)。

You have a couple of options.你有几个选择。 You can provide an empty array as the default value for elements in a for ... in loop:您可以提供一个空数组作为for ... in循环中elements的默认值:

let elements: [Element]?

for element in elements ?? [] {

}

Or you can use forEach and optional chaining on elements或者您可以在elements上使用forEach和可选链接

elements?.forEach { element in

}

Bear in mind that optional collections are an anti-pattern in Swift.请记住,可选集合是 Swift 中的一种反模式。 You can represent the lack of value using an empty collection, so wrapping a collection in an optional doesn't provide any extra value, while complicating the interface.您可以使用空集合表示缺少值,因此将集合包装在可选中不会提供任何额外的值,同时会使接口复杂化。

Your elements are not optional, but array is.您的元素不是可选的,但数组是可选的。 In your case just unwrap the array:在您的情况下,只需解开数组:

let elements: [Element]?
for element in elements ?? [] {
    // do stuff
}

But if your elements are optional, you can use compactMap:但是如果你的元素是可选的,你可以使用 compactMap:

let elements: [Element?] // elements are optional instead of array
for element in elements.compactMap { $0 } {
    // do stuff
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM