我需要一种功能方法来处理这种情况:我有两个相同对象类型的数组,我需要创建一个函数,返回具有相同ID的这些对象的元组数组。
这是强制实施:
func filterById(personArray : [Person], anotherPersonArray : [Person]) -> [(Person,Person)]{
var ret = [(Person,Person)]()
for person in personArray{
for person2 in anotherPersonArray{
if person.id?.intValue == person2.id?.intValue{
ret.append(person,person2)
}
}
}
return ret
现在我的功能尝试实现这一点,但总是返回一个空数组
return Array(zip(personArray,anotherPersonArray)).filter
{$0.id?.intValue == $1.id?.intValue}}}
我如何对此进行功能性处理?
答案 0 :(得分:2)
你基本上可以做@toskv在他的评论中所说的:笛卡尔积,然后用相同的id过滤。你可以这样做:
func filterById(a : [Person], b : [Person]) -> [(Person, Person)] {
let lazyCartProd = a.lazy.map{ p in
b.lazy.map{ (p, $0) }
}.flatten()
let lazySame = lazyCartProd.filter{ $0.id == $1.id }
return Array(lazySame)
}
请注意,没有创建中间数组,因为它是惰性的。你也可以将它打包成一个声明,但我没有因为清晰。
有趣的事情:lazySame
的类型为:
LazyFilterCollection<FlattenBidirectionalCollection<LazyMapCollection<Array<Person>, LazyMapCollection<Array<Person>, (Person, Person)>>>>
这就是为什么类型推断很酷:D
可能你根本不应该使用数组,如果你的Person
类型符合Hashable
,你可以把它放在Set
中并使用更有效的方法比如intersect
,contains
,union
等等,其复杂程度比使用数组的时间要好n
倍。
答案 1 :(得分:1)
试试这个:
return personArray.map {
p -> [(Person, Person)] in
anotherPersonArray
.filter { $0.id == p.id }
.map { (p, $0) }
}.flatMap { $0 }
我假设id
在每个数组中都是唯一的。 SwiftStub