功能方法:合并两个数组并使用常见对象返回元组

时间:2015-09-30 20:19:41

标签: arrays swift functional-programming

我需要一种功能方法来处理这种情况:我有两个相同对象类型的数组,我需要创建一个函数,返回具有相同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}}}

我如何对此进行功能性处理?

2 个答案:

答案 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中并使用更有效的方法比如intersectcontainsunion等等,其复杂程度比使用数组的时间要好n倍。

答案 1 :(得分:1)

试试这个:

return personArray.map {
    p -> [(Person, Person)] in
    anotherPersonArray
        .filter { $0.id == p.id }
        .map { (p, $0) }
}.flatMap { $0 }

我假设id在每个数组中都是唯一的。 SwiftStub