使用hasSuffix返回一个元组

时间:2017-09-13 08:52:03

标签: swift

我从一本书中学得很快,我遇到了一个我不知道如何解决的挑战。

以下是挑战:编写一个名为siftBeans(fromGroceryList:)的函数,它将一个购物清单(作为字符串数组)和“筛选出”来自其他杂货的咖啡豆。该函数应该采用一个名为list的参数名称的参数,并且它应该返回一个(beans: [String], otherGroceries: [String])类型的命名元组。

以下是您应该如何调用函数以及结果应该是什么的示例:

let result = siftBeans(fromGroceryList: ["green beans",
                                         "milk",
                                         "black beans",
                                         "pinto beans",
                                         "apples"])

result.beans == ["green beans", "black beans", "pinto beans"] // true
result.otherGroceries == ["milk", "apples"] // true

提示:您可能需要在名为hasSuffix(_:)的String类型上使用函数。

3 个答案:

答案 0 :(得分:1)

这就是我写函数的方法。

func siftBeans(groceries: [String]) -> (beans: [String], otherGroceries: [String]) {
    return (
        groceries.filter { $0.hasSuffix("beans") },
        groceries.filter { !$0.hasSuffix("beans") }
    )
}

过滤器功能使用hasSuffix来确定是否应包含项目。所以我只运行两次,一次获取所有...beans项,一次获得其余项目。

它会对数组进行两次迭代,但这不是什么大问题。我实际上有一个函数在一个数组上执行filterInOut,为任何数组执行此操作。

修改

我想改进这一点,看看我是否能提供更好的通用替代方案。

所以我提出了这个......

extension Collection {
    func separated(_ divisor: (Iterator.Element) -> (Bool)) -> (in: [Iterator.Element], out: [Iterator.Element]) {
        return reduce((in: [], out: [])) {
            divisor($1) ? ($0.in + [$1], $0.out) : ($0.in, $0.out + [$1])
        }
    }
}

它是Collection的扩展名,因此可用于任何类型的集合。它需要一个返回Bool的闭包。结果是一个元组(in: [], out: []),它使用闭包来以任何方式过滤项目。

它可以像这样使用......

let array = [1, 2, 3, 4, 5, 6, 7, 8]
array.separated { $0 % 2 == 0 } // ([2, 4, 6, 8], [1, 3, 5, 7])

或者,在您的用例中......

let array = ["green beans", "milk", "black beans", "pinto beans", "apples"]
array.separated { $0.hasSuffix("beans") } // (["green beans", "black beans", "pinto beans"], ["milk", "apples"])

希望有所帮助:D

答案 1 :(得分:0)

元组项可以具有类似函数参数的名称。这是你正在寻找的功能

func siftBeans(from groceryList: [String]) -> (beans: [String], otherGroceries: [String]) {
    var beans = [String]()
    var otherGroceries = [String]()
    groceryList.forEach { (grocery) in
        grocery.hasSuffix("beans") ? beans.append(grocery) : otherGroceries.append(grocery)
    }
    return (beans , otherGroceries)
}

答案 2 :(得分:0)

您还可以将单个Set.substracting操作与filter结合使用,这样您只需要在原始数组上调用func filterBeans(groceryList: [String])->(beans: [String], otherGroceries: [String]){ let beans = groceryList.filter({$0.hasSuffix("beans")}) let otherGroceries = Array(Set(groceryList).subtracting(beans)) return (beans, otherGroceries) } 一次而不是调用它两次(对于具有后缀的元素,只需调用一次)并且一旦没有它的元素。)

groceryList

当然,为了实现这一点,输入Set只需要具有唯一元素(否则创建中间{{1}}将删除重复项。)