Swift - 如何获取数组过滤项的索引
Posted
技术标签:
【中文标题】Swift - 如何获取数组过滤项的索引【英文标题】:Swift - How to get indexes of filtered items of array 【发布时间】:2017-08-29 07:27:01 【问题描述】:let items: [String] = ["A", "B", "A", "C", "A", "D"]
items.whatFunction("A") // -> [0, 2, 4]
items.whatFunction("B") // -> [1]
Swift 3 是否支持whatFunction(_: Element)
之类的函数?
如果不是,最有效的逻辑是什么?
【问题讨论】:
你可以这样找到 let indexOfA = arr.index(of: "a") @BhupatBheda 谢谢,但index(of: Element)
只返回Int?
。我需要的函数应该返回[Int]?
。
After Swift 3 conversion, I can't get rid of error: "Ambiguous use of 'indexOfObject(passingTest:)'"的可能重复
【参考方案1】:
您可以直接过滤数组的indices
,这样可以避免多余的map
ping。
let items = ["A", "B", "A", "C", "A", "D"]
let filteredIndices = items.indices.filter items[$0] == "A"
或作为Array
扩展名:
extension Array where Element: Equatable
func whatFunction(_ value : Element) -> [Int]
return self.indices.filter self[$0] == value
items.whatFunction("A") // -> [0, 2, 4]
items.whatFunction("B") // -> [1]
或者更通用的
extension Collection where Element: Equatable
func whatFunction(_ value : Element) -> [Index]
return self.indices.filter self[$0] == value
【讨论】:
您不妨扩展Collection
,因为该实现不使用任何特定于数组的内容。
@vadian 你想检查***.com/q/54088250/4601170 并请帮助我吗?【参考方案2】:
您可以为数组创建自己的扩展。
extension Array where Element: Equatable
func indexes(of element: Element) -> [Int]
return self.enumerated().filter( element == $0.element ).map( $0.offset )
你可以这样称呼它
items.indexes(of: "A") // [0, 2, 4]
items.indexes(of: "B") // [1]
【讨论】:
太棒了!谢谢! 这是一个 EF'n 绝妙的答案! 嗨,它返回 null 了吗?【参考方案3】:您可以通过以下方式实现此目的:
enumerated()
- 添加索引;
filter()
淘汰不必要的物品;
map()
我们的索引。
示例(适用于 Swift 3 - Swift 4.x):
let items: [String] = ["A", "B", "A", "C", "A", "D"]
print(items.enumerated().filter( $0.element == "A" ).map( $0.offset )) // -> [0, 2, 4]
另一种方法是使用flatMap
,它允许您在一个闭包中检查元素并在需要时返回索引。
示例(适用于 Swift 3 - Swift 4.0):
print(items.enumerated().flatMap $0.element == "A" ? $0.offset : nil ) // -> [0, 2, 4]
但由于 Swift 4.1 flatMap
可以返回非 nil 对象已被弃用,您应该改用 compactMap
。
示例(从 Swift 4.1 开始工作):
print(items.enumerated().compactMap $0.element == "A" ? $0.offset : nil ) // -> [0, 2, 4]
最干净和最节省内存的方法是遍历数组 indices 并检查当前索引处的数组元素是否等于所需元素。
示例(适用于 Swift 3 - Swift 5.x):
print(items.indices.filter( items[$0] == "A" )) // -> [0, 2, 4]
【讨论】:
请注意,您也可以像 Julien 那样将过滤器和地图组合到 flatMap 中,但答案中的更多细节也很好;) @DavidBerry,当然,但我认为这对作者来说是更高级的话题) 哇,好答案! 感谢索引建议。这正是我需要清理一个尴尬的单班轮 谢谢,很好的回答【参考方案4】:在 Swift 3 和 Swift 4 中,您可以这样做:
let items: [String] = ["A", "B", "A", "C", "A", "D"]
extension Array where Element: Equatable
func indexes(of item: Element) -> [Int]
return enumerated().compactMap $0.element == item ? $0.offset : nil
items.indexes(of: "A")
希望我的回答对你有所帮助?
【讨论】:
【参考方案5】:你可以这样使用它:
let items: [String] = ["A", "B", "A", "C", "A", "D"]
let indexes = items.enumerated().filter
$0.element == "A"
.map$0.offset
print(indexes)
【讨论】:
【参考方案6】:复制粘贴
extension Array
func whatFunction(_ ids : String) -> [Int]
var mutableArr = [Int]()
for i in 0..<self.count
if ((self[i] as! String) == ids)
mutableArr.append(i)
return mutableArr
【讨论】:
【参考方案7】:您可以使用以下代码:
var firstArray = ["k","d","r","r","p","k","b","p","k","k"]
var secondArray = ["k","d","r","s","d","r","b","c"]
let filterArray = firstArray.filter secondArray.contains($0)
let filterArray1 = firstArray.filter !secondArray.contains($0)
let filterIndex = firstArray.enumerated().filter $0.element == "k" .map $0.offset
print(filterArray) --> // ["k", "d", "r", "r", "k", "b", "k", "k"]
print(filterArray1) --> // ["p", "p"]
print(filterIndex) --> // [0, 5, 8, 9]
【讨论】:
【参考方案8】:这也是一种方式
// MARK: - ZIP: Dictionary like
let words = ["One", "Two", "Three", "Four"]
let numbers = 1...words.count
for (word, number) in zip(words, numbers)
print("\n\(word): \(number)")
【讨论】:
【参考方案9】:例如查找 inds1 数组中 p_last 值的索引:(swift 4+)
let p_last = [51,42]
let inds1 = [1,3,51,42,4]
let idx1 = Array(inds1.filter p_last.contains($0) .indices)
idx1 = [0,1]
【讨论】:
以上是关于Swift - 如何获取数组过滤项的索引的主要内容,如果未能解决你的问题,请参考以下文章