Swift在Underscore.js中有类似_.findWhere的内容吗?
我有一个T
类型的结构数组,并想检查数组是否包含name
属性等于Foo
的结构对象。
尝试使用find()
和filter()
,但它们仅适用于原始类型,例如String
或Int
。引发错误,指出不符合Equitable
协议或类似协议。
答案 0 :(得分:216)
SWIFT 3/4/5
检查元素是否存在
if array.contains(where: {$0.name == "foo"}) {
// it exists, do something
} else {
//item could not be found
}
获取元素
if let foo = array.first(where: {$0.name == "foo"}) {
// do something with foo
} else {
// item could not be found
}
获取元素及其偏移量
if let foo = array.enumerated().first(where: {$0.element.name == "foo"}) {
// do something with foo.offset and foo.element
} else {
// item could not be found
}
获取偏移量(更新)
if let fooOffset = array.firstIndex(where: {$0.name == "foo"}) {
// do something with fooOffset
} else {
// item could not be found
}
答案 1 :(得分:117)
您可以使用index
上的Array
方法和谓词(see Apple's documentation here)。
func index(where predicate: (Element) throws -> Bool) rethrows -> Int?
对于您的具体示例,这将是:
Swift 3.0
if let i = array.index(where: { $0.name == Foo }) {
return array[i]
}
Swift 2.0
if let i = array.indexOf({ $0.name == Foo }) {
return array[i]
}
答案 2 :(得分:80)
FWIW,如果您不想使用自定义功能或扩展程序,您可以:
let array = [ .... ]
if let found = find(array.map({ $0.name }), "Foo") {
let obj = array[found]
}
首先生成name
数组,然后生成find
。
如果您有大阵列,您可能想要这样做:
if let found = find(lazy(array).map({ $0.name }), "Foo") {
let obj = array[found]
}
或者也许:
if let found = find(lazy(array).map({ $0.name == "Foo" }), true) {
let obj = array[found]
}
答案 3 :(得分:38)
Swift 3
如果您需要使用对象:
array.first{$0.name == "Foo"}
(如果你有多个名为“Foo”的对象,那么first
将从未指定的顺序返回第一个对象)
答案 4 :(得分:20)
Swift 3.0
if let index = array.index(where: { $0.name == "Foo" }) {
return array[index]
}
Swift 2.1
swift 2.1现在支持过滤对象属性。您可以根据结构或类的任何值过滤您的数组,这是一个示例
for myObj in myObjList where myObj.name == "foo" {
//object with name is foo
}
OR
for myObj in myObjList where myObj.Id > 10 {
//objects with Id is greater than 10
}
答案 5 :(得分:18)
您可以过滤数组,然后选择第一个元素,如图所示 在Find Object with Property in Array。
或者您定义自定义扩展程序
extension Array {
// Returns the first element satisfying the predicate, or `nil`
// if there is no matching element.
func findFirstMatching<L : BooleanType>(predicate: T -> L) -> T? {
for item in self {
if predicate(item) {
return item // found
}
}
return nil // not found
}
}
用法示例:
struct T {
var name : String
}
let array = [T(name: "bar"), T(name: "baz"), T(name: "foo")]
if let item = array.findFirstMatching( { $0.name == "foo" } ) {
// item is the first matching array element
} else {
// not found
}
在 Swift 3 中,您可以使用现有的first(where:)
方法
(作为mentioned in a comment):
if let item = array.first(where: { $0.name == "foo" }) {
// item is the first matching array element
} else {
// not found
}
答案 6 :(得分:8)
Swift 3
你可以在Swift 3中使用index(where :)
func index(where predicate: @noescape Element throws -> Bool) rethrows -> Int?
例如
if let i = theArray.index(where: {$0.name == "Foo"}) {
return theArray[i]
}
答案 7 :(得分:7)
Swift 4 ,
实现这一目标的另一种方法 使用过滤功能,
if let object = elements.filter({ $0.title == "title" }).first {
print("found")
} else {
print("not found")
}
答案 8 :(得分:3)
Swift 3
if yourArray.contains(item) {
//item found, do what you want
}
else{
//item not found
yourArray.append(item)
}
答案 9 :(得分:2)
Swift 2或更高版本
您可以合并indexOf
和map
来编写&#34;查找元素&#34;功能在一条线上。
let array = [T(name: "foo"), T(name: "Foo"), T(name: "FOO")]
let foundValue = array.indexOf { $0.name == "Foo" }.map { array[$0] }
print(foundValue) // Prints "T(name: "Foo")"
使用filter
+ first
看起来更干净,但filter
会评估数组中的所有元素。 indexOf
+ map
看起来很复杂,但是当找到数组中的第一个匹配项时,评估会停止。这两种方法都有利有弊。
答案 10 :(得分:1)
使用contains
:
var yourItem:YourType!
if contains(yourArray, item){
yourItem = item
}
或者您可以在评论中尝试Martin指出的内容并再次尝试filter
:Find Object with Property in Array。
答案 11 :(得分:1)
访问array.index(of:Any)的另一种方法是声明你的对象
import Foundation
class Model: NSObject { }
答案 12 :(得分:1)
使用Dollar作为Swift的Lo-Dash或Underscore.js:
plot <- read_csv("AFGP60 UV-05-04-16.csv",
col_names = FALSE, na = "null", skip = 2,n_max = numrow)
diffplot <- c(plot[1:601,2])
diffplot <- lapply(diffplot,as.double)
findpeaks(diffplot)`
答案 13 :(得分:1)
斯威夫特3:
您可以使用Swifts内置功能在阵列中查找自定义对象。
首先,您必须确保自定义对象符合: Equatable协议。
class Person : Equatable { //<--- Add Equatable protocol
let name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
//Add Equatable functionality:
static func == (lhs: Person, rhs: Person) -> Bool {
return (lhs.name == rhs.name)
}
}
通过向对象添加Equatable功能,Swift现在将向您显示可在阵列上使用的其他属性:
//create new array and populate with objects:
let p1 = Person(name: "Paul", age: 20)
let p2 = Person(name: "Mike", age: 22)
let p3 = Person(name: "Jane", age: 33)
var people = [Person]([p1,p2,p3])
//find index by object:
let index = people.index(of: p2)! //finds Index of Mike
//remove item by index:
people.remove(at: index) //removes Mike from array
答案 14 :(得分:1)
对于Swift 3,
let index = array.index(where: {$0.name == "foo"})
答案 15 :(得分:0)
例如,如果我们有一个数字数组:
let numbers = [2, 4, 6, 8, 9, 10]
我们可以找到这样的第一个奇数:
let firstOdd = numbers.index { $0 % 2 == 1 }
这将作为可选整数发送回4,因为第一个奇数(9)位于索引4。