我有两个数组
let toBeFiltered = ["star0", "star2", "star1", "star0", "star3", "star4"]
let theFilter = ["star1", "star3"]
如何使用第二个数组过滤第一个数组?实际上
theFilter
可以动态改变,例如,
let theFilter = ["star2"]
or maybe
let theFilter = ["star0", "star4", "star2"]
感谢您的帮助:)
使用 设置操作
Set(toBeFiltered).intersection(Set(theFilter))
let toBeFiltered = ["star0", "star2", "star1", "star0", "star3", "star4"]
let theFilter = ["star1", "star3"]
let filtered = toBeFiltered.filter(theFilter.contains)
您还可以过滤结构数组
struct myStruct
{
var userid:String;
var details:String;
init() {
userid = "default value";
details = "default";
}
};
var f1 = myStruct();
f1.userid = "1";
f1.details = "Good boy";
var f2 = myStruct();
f2.userid = "2";
f2.details = "Bad boy";
var f3 = myStruct();
f3.userid = "3";
f3.details = "Gentleman";
var arrNames1:Array = [f1,f3];
var arrNames2:Array = [f3,f1,f2];
let filteredArrayStruct = arrNames1.filter( { (user: myStruct) -> Bool in
return arrNames2.contains({ (user1: myStruct) -> Bool in
return user.userid == user1.userid;
})
})
print(filteredArrayStruct)
对于 Set 必须符合 Hashable 协议
class mytestclass: Hashable
{
var userid:Int ;
var details:String;
var hashValue: Int {
return self.userid
}
init(userid: Int, details:String)
{
self.userid = userid;
self.details = details;
}
}
func ==(lhs: mytestclass, rhs: mytestclass) -> Bool {
return lhs.userid == rhs.userid
}
var t1 = mytestclass(userid: 1,details: "Good boy");
var t2 = mytestclass(userid: 2,details: "bad boy");
var t3 = mytestclass(userid: 3,details: "gentle man");
var classArrayNames:Set<mytestclass> = [t1,t2];
var classArrayNames2:Set<mytestclass> = [t3,t1,t2];
let result = Set(classArrayNames).intersect(classArrayNames2)
这似乎是今天的一个主题:)建立在另一个很好的答案的基础上,我建议在
intersect(_:)
上使用Set
方法:
let toBeFiltered = ["star0", "star2", "star1", "star0", "star3", "star4"]
let theFilter = ["star1", "star3"]
let filtered = Set(toBeFiltered).intersect(theFilter)
// => ["star1", "star3"] of type Set<String>
// ...if you actually need an array, you can get one using Array(filtered)
let mainArray = ["one", "two", "three", "three", "three", "four", "five"]
let miniArray = ["two", "three"]
let leftOvers = mainArray.filter( {miniArray.contains($0) == false} )
print(leftOvers)
虽然按照 Arsen 的建议使用 Sets 绝对是最优雅的,但有时你想保留 duplicates 和 order:
//: Playground - noun: a place where people can play
import Foundation
extension Collection where Element: Equatable {
func intersection(with filter: [Element]) -> [Element] {
return self.filter { element in filter.contains(element) }
}
}
let toBeFiltered = ["star0", "star2", "star1", "star0", "star3", "star4", "star1"]
let theFilter = ["star1", "star3"]
let filtered = toBeFiltered.intersection(with: theFilter) // ["star1", "star3", "star1"]
您可以组合 Swift 中可用的过滤器和包含函数:
func filter(_ isInincluded: (Self.Element) throws -> Bool) re throws -> [Self.Element]
func contains(where predicate: (Self.Element) throws -> Bool) re throws -> Bool
contains:返回一个布尔值,指示序列是否包含满足给定谓词的元素。
struct Team {
var id: String
var name: String
var logo: String
}
struct Matches {
var date: String?
var description: String?
var name: String?
var winner: String?
var highlights: String?
}
var upcoming: [Matches] = []
var selectedTeams: [Team] = []
// Do filter
var filterUpcoming = upcoming.filter { matches in
return selectedTeams.contains { team in
return matches.name == team.name
}
}