使用函数在Swift中查找两个序列中的公共元素

use*_*142 20 swift

我正在尝试完成Apple新书"The Swift Programming Language"第46页的练习.它给出了以下代码:

func anyCommonElements <T, U where T: Sequence, U: Sequence, T.GeneratorType.Element: Equatable, T.GeneratorType.Element == U.GeneratorType.Element> (lhs: T, rhs: U) -> Bool {
    for lhsItem in lhs {
        for rhsItem in rhs {
            if lhsItem == rhsItem {
                return true
            }
        }
    }
    return false
}
anyCommonElements([1, 2, 3], [3])
Run Code Online (Sandbox Code Playgroud)

练习是更改函数,以便返回两个序列都具有的所有元素.为此,我尝试使用以下代码:

func anyCommonElements <T, U where T: Sequence, U: Sequence, T.GeneratorType.Element:     Equatable, T.GeneratorType.Element == U.GeneratorType.Element> (lhs: T, rhs: U) -> T.GeneratorType[] {
    var toReturn = T.GeneratorType[]()
    for lhsItem in lhs {
        for rhsItem in rhs {
            if lhsItem == rhsItem {
                toReturn.append(lhsItem)
            }
        }
    }
    return toReturn
}
anyCommonElements([1, 2, 3], [3])
Run Code Online (Sandbox Code Playgroud)

但在第2行,我收到错误:无法找到成员'下标'

这个错误的原因是什么?这个问题的最佳解决方案是什么?

Con*_*nor 27

通过使返回值为T.GeneratorType.Element数组,我能够使它工作.

func anyCommonElements <T, U where T: SequenceType, U: SequenceType, T.Generator.Element: Equatable, T.Generator.Element == U.Generator.Element> (lhs: T, rhs: U) -> Array<T.Generator.Element> {
    var toReturn = Array<T.Generator.Element>()
    for lhsItem in lhs {
        for rhsItem in rhs {
            if lhsItem == rhsItem {
                toReturn.append(lhsItem)
            }
        }
    }
    return toReturn
}
anyCommonElements([1, 2, 3], [3])
Run Code Online (Sandbox Code Playgroud)

  • 知道为什么var toReturn = Array <T.GeneratorType.Element>()有效,但var toReturn = [T.GeneratorType.Element]()会出错吗? (8认同)

Nic*_*uet 10

从Swift 3开始,Generator协议被重命名为Iterator协议:( 链接到github提议)

所以,需要编写函数:

func commonElements<T: Sequence, U: Sequence>(_ lhs: T, _ rhs: U) -> [T.Iterator.Element]
    where T.Iterator.Element: Equatable, T.Iterator.Element == U.Iterator.Element {
        var common: [T.Iterator.Element] = []

        for lhsItem in lhs {
            for rhsItem in rhs {
                if lhsItem == rhsItem {
                    common.append(lhsItem)
                }
            }
        }
        return common
}
Run Code Online (Sandbox Code Playgroud)


小智 8

我在上面两个解决方案中遇到了编译器错误,我在Xcode 6.01操场上运行了iBook的指南.我有关于我在这里找到的数组声明的一致编译器投诉,所以我假设海报可能正在使用早期版本的swift.如果我错了,那就知道了.

对于数组声明,我发现了

    var thingList : [ThingType] = []
Run Code Online (Sandbox Code Playgroud)

我一直工作,所以我倾向于这样做,放弃

    var thing[],thing[]()  // gave compiler errors/warnings
Run Code Online (Sandbox Code Playgroud)

我的环境永远无法解决名为T.GeneratorType [.Element]的问题

我为这个实验找到的解决方案是


func anyCommonElements <T, U
                    where
                    T: SequenceType, U: SequenceType,
                    T.Generator.Element: Equatable,
                    T.Generator.Element == U.Generator.Element>
                    (lhs: T, rhs: U)
-> [T.Generator.Element]
{
    var  returnValue: [T.Generator.Element] = []
    for lhsItem in lhs {
        for rhsItem in rhs {
           if lhsItem == rhsItem {
              returnValue.append(lhsItem)
           }
        }
    }
    return returnValue
}

let commonNumberList = anyCommonElements([1, 2, 3,4,5,6,7,8], [2,3,9,14,8,21])
println("common Numbers = \(commonNumberList)")

let commonStringList = anyCommonElements(["a","b","c"],["d","e","f","c","b"])
println("common Strings = \(commonStringList)")
Run Code Online (Sandbox Code Playgroud)

教程文本真的没有准备好我实际解决实验而没有额外的阅读.感谢大家在这里贡献他们的解决方案,它确实帮助我对Swift进行了很好的介绍.