Swift 通用数组函数,用于查找与项目不匹配的元素的所有索引
Swift generic array function to find all indexes of elements not matching item
Swift 3
正在尝试编写一个通用数组扩展,以获取不等于值的项目的所有索引
示例
let arr: [String] = ["Empty", "Empty", "Full", "Empty", "Full"]
let result: [Int] = arr.indexes(ofItemsNotEqualTo item: "Empty")
//returns [2, 4]
我尝试创建一个通用函数:
extension Array {
func indexes<T: Equatable>(ofItemsNotEqualTo item: T) -> [Int]? {
var result: [Int] = []
for (n, elem) in self.enumerated() {
if elem != item {
result.append(n)
}
}
return result.isEmpty ? nil : result
}
}
但这会给出警告:二元运算符不能应用于 "Element" 和 "T".
类型的操作数
然后我在投射元素的地方做了这个(注意 as?)
extension Array {
func indexes<T: Equatable>(ofItemsNotEqualTo item: T) -> [Int]? {
var result: [Int] = []
for (n, elem) in self.enumerated() {
if elem as? T != item {
result.append(n)
}
}
return result.isEmpty ? nil : result
}
}
但现在似乎类型检查已经结束 window,因为如果我传入一个整数,我会得到错误的结果
let arr: [String] = ["Empty", "Empty", "Full", "Empty", "Full"]
let result: [Int] = arr.indexes(ofItemsNotEqualTo item: 100)
//returns [0, 1, 2, 3, 4]
将不胜感激。
使用 reduce 函数有更好的方法吗?
您已经定义了一个泛型方法
func indexes<T: Equatable>(ofItemsNotEqualTo item: T) -> [Int]?
需要一个 T
类型的参数
Equatable
,但与数组的 Element
类型无关。
因此
let arr = ["Empty", "Empty", "Full", "Empty", "Full"]
let result = arr.indexes(ofItemsNotEqualTo: 100)
编译,但 elem as? T
给出 nil
(即 != item
)
对于所有数组元素。
你想要的是一个只为数组定义的方法
Equatable
个元素。这可以通过约束来实现
扩展名:
extension Array where Element: Equatable {
func indexes(ofItemsNotEqualTo item: Element) -> [Int]? {
var result: [Int] = []
for (n, elem) in enumerated() {
if elem != item {
result.append(n)
}
}
return result.isEmpty ? nil : result
}
}
实际上我不会将 return 值设为可选值。
如果所有元素都等于给定的项目,则逻辑
return 值将是空数组。
Is there a better way to do this with the reduce function?
好吧,你 可以 使用 reduce()
,但这不是很有效,因为在每个迭代步骤中都会创建中间数组:
extension Array where Element: Equatable {
func indexes(ofItemsNotEqualTo item: Element) -> [Int] {
return enumerated().reduce([]) {
.element == item ? [=13=] : [=13=] + [.offset]
}
}
}
你实际拥有的是
"filter + map" 操作:
extension Array where Element: Equatable {
func indexes(ofItemsNotEqualTo item: Element) -> [Int] {
return enumerated().filter { [=14=].element != item }.map { [=14=].offset }
}
}
可以使用flatMap()
简化:
extension Array where Element: Equatable {
func indexes(ofItemsNotEqualTo item: Element) -> [Int] {
return enumerated().flatMap { [=15=].element != item ? [=15=].offset : nil }
}
}
示例:
let arr = ["Empty", "Empty", "Full", "Empty", "Full"]
arr.indexes(ofItemsNotEqualTo: "Full") // [0, 1, 3]
[1, 1, 1].indexes(ofItemsNotEqualTo: 1) // []
arr.indexes(ofItemsNotEqualTo: 100)
// error: cannot convert value of type 'Int' to expected argument type 'String'
Swift 3
正在尝试编写一个通用数组扩展,以获取不等于值的项目的所有索引
示例
let arr: [String] = ["Empty", "Empty", "Full", "Empty", "Full"]
let result: [Int] = arr.indexes(ofItemsNotEqualTo item: "Empty")
//returns [2, 4]
我尝试创建一个通用函数:
extension Array {
func indexes<T: Equatable>(ofItemsNotEqualTo item: T) -> [Int]? {
var result: [Int] = []
for (n, elem) in self.enumerated() {
if elem != item {
result.append(n)
}
}
return result.isEmpty ? nil : result
}
}
但这会给出警告:二元运算符不能应用于 "Element" 和 "T".
类型的操作数然后我在投射元素的地方做了这个(注意 as?)
extension Array {
func indexes<T: Equatable>(ofItemsNotEqualTo item: T) -> [Int]? {
var result: [Int] = []
for (n, elem) in self.enumerated() {
if elem as? T != item {
result.append(n)
}
}
return result.isEmpty ? nil : result
}
}
但现在似乎类型检查已经结束 window,因为如果我传入一个整数,我会得到错误的结果
let arr: [String] = ["Empty", "Empty", "Full", "Empty", "Full"]
let result: [Int] = arr.indexes(ofItemsNotEqualTo item: 100)
//returns [0, 1, 2, 3, 4]
将不胜感激。
使用 reduce 函数有更好的方法吗?
您已经定义了一个泛型方法
func indexes<T: Equatable>(ofItemsNotEqualTo item: T) -> [Int]?
需要一个 T
类型的参数
Equatable
,但与数组的 Element
类型无关。
因此
let arr = ["Empty", "Empty", "Full", "Empty", "Full"]
let result = arr.indexes(ofItemsNotEqualTo: 100)
编译,但 elem as? T
给出 nil
(即 != item
)
对于所有数组元素。
你想要的是一个只为数组定义的方法
Equatable
个元素。这可以通过约束来实现
扩展名:
extension Array where Element: Equatable {
func indexes(ofItemsNotEqualTo item: Element) -> [Int]? {
var result: [Int] = []
for (n, elem) in enumerated() {
if elem != item {
result.append(n)
}
}
return result.isEmpty ? nil : result
}
}
实际上我不会将 return 值设为可选值。 如果所有元素都等于给定的项目,则逻辑 return 值将是空数组。
Is there a better way to do this with the reduce function?
好吧,你 可以 使用 reduce()
,但这不是很有效,因为在每个迭代步骤中都会创建中间数组:
extension Array where Element: Equatable {
func indexes(ofItemsNotEqualTo item: Element) -> [Int] {
return enumerated().reduce([]) {
.element == item ? [=13=] : [=13=] + [.offset]
}
}
}
你实际拥有的是 "filter + map" 操作:
extension Array where Element: Equatable {
func indexes(ofItemsNotEqualTo item: Element) -> [Int] {
return enumerated().filter { [=14=].element != item }.map { [=14=].offset }
}
}
可以使用flatMap()
简化:
extension Array where Element: Equatable {
func indexes(ofItemsNotEqualTo item: Element) -> [Int] {
return enumerated().flatMap { [=15=].element != item ? [=15=].offset : nil }
}
}
示例:
let arr = ["Empty", "Empty", "Full", "Empty", "Full"]
arr.indexes(ofItemsNotEqualTo: "Full") // [0, 1, 3]
[1, 1, 1].indexes(ofItemsNotEqualTo: 1) // []
arr.indexes(ofItemsNotEqualTo: 100)
// error: cannot convert value of type 'Int' to expected argument type 'String'