如何根据名称数组过滤数组?

时间:2017-05-21 05:15:47

标签: arrays swift filter

我有2个数组。在第一个数组中,我有一个名单,我想从第二个数组中删除。

第一个数组只是字符串数组:

var arrayNames = ["apple", "apricot", "cucumber"]

第二个数组是自定义structs

的数组
struct fruitsData {
var name: String?
}

var secondArray = [fruitsData(name: "apple"),fruitsData(name: "apricot"), fruitsData(name: "mango"), fruitsData(name: "grapes"), fruitsData(name: "tomato"), fruitsData(name: "lichi"), fruitsData(name: "cucumber"), fruitsData(name: "brinjal")]

那么我怎样才能得到只包含这些数据的数组:

var finalData = [fruitsData(name: "mango"), fruitsData(name: "grapes"), fruitsData(name: "tomato"), fruitsData(name: "lichi"), fruitsData(name: "brinjal")]

,其中不包含arrayNames的任何名称?

5 个答案:

答案 0 :(得分:1)

有几种方法可以做到这一点:

  • 最好的方法是使用filter方法:

    var arrayNames = ["apple", "apricot", "cucumber"]
    var secondArray = [fruitsData(name: "apple"),fruitsData(name: "apricot"), fruitsData(name: "mango"), fruitsData(name: "grapes"), fruitsData(name: "tomato"), fruitsData(name: "lichi"), fruitsData(name: "cucumber"), fruitsData(name: "brinjal")]
    
    secondArray = secondArray.filter({$0.name != nil && !arrayNames.contains($0.name!)})
    
  • 或者,如果您想为了可读性而牺牲效率,可以在辅助数组旁边使用for-in循环:

    var arrayNames = ["apple", "apricot", "cucumber"]
    var secondArray = [fruitsData(name: "apple"),fruitsData(name: "apricot"), fruitsData(name: "mango"), fruitsData(name: "grapes"), fruitsData(name: "tomato"), fruitsData(name: "lichi"), fruitsData(name: "cucumber"), fruitsData(name: "brinjal")]
    var helperArray = [fruitsData]()
    
    for fruit in secondArray {
    
        if fruit.name != nil && !arrayNames.contains(fruit.name!){
            helperArray.append(fruit)
        }
    
    }
    
    secondArray = helperArray
    

以上内容将清除secondArray中包含arrayNames名称的所有元素。您应该熟悉 Map, Filter and Reduce

答案 1 :(得分:1)

finalData secondArray arrayNamesvar finalData = secondArray.filter { !arrayNames.contains($0.name!)} 之外的kotlinc-jvm可以在此处完成。 。

kotlinc

答案 2 :(得分:0)

我正在打电话,所以我无法检查,但这应该可以解决问题

secondArray.filter { !firstArray.contains($0.name) }

答案 3 :(得分:0)

当想要从给定数组和某个谓词构造子集数组时,自然方法是使用filter。由于name结构的FruitsDataOptional,因此在将其与Optional中的非arrayNames名称进行比较之前,您需要(尝试)展开它。 {1}}列表,例如使用map(_:)的{​​{1}}方法以及可选链接来处理Optional - 值nil个案例。

E.g:

name

由于// example setup struct FruitsData { var name: String? } let arrayNames = ["apple", "apricot", "cucumber"] let secondArray = [ FruitsData(name: "apple"), FruitsData(name: "apricot"), FruitsData(name: "mango"), FruitsData(name: "grapes"), FruitsData(name: "tomato"), FruitsData(name: "lichi"), FruitsData(name: "cucumber"), FruitsData(name: "brinjal") ] // filter 'secondArray' based on the non-existance of an // associated fruit name in the 'arrayNames' list let finalData = secondArray.filter { $0.name.map { fruitName in !arrayNames.contains(fruitName) } ?? true } 符合String,您可能还需要考虑将要删除的水果名称列表(Hashable)设为arrayNames而不是Set {1}},因为前者在将Array应用于O(1)时会允许contains { ... }查找。 E.g:

let removeNames = Set(arrayNames)
let finalData = secondArray.filter {
    $0.name.map { fruitName in !removeNames.contains(fruitName) } ?? true
}                                        /* ^^^^^^^^- O(1) lookup */

如果您还希望过滤掉FruitsDatasecondArraynilname个属性的... ?? true个实例,您可以使用... ?? false谓词部分上方为filterFruitsData操作将过滤掉name属性为nil属性arrayNames// ... filter out also FruitsData instances with 'nil' valued 'name' let removeNames = Set(arrayNames) let finalData = secondArray.filter { $0.name.map { fruitName in !removeNames.contains(fruitName) } ?? false } 中存在的所有{{1}}个实例。

{{1}}

答案 4 :(得分:0)

如果名称不是空字符串,则可以使用

let arrayNames = ["apple"]

struct fruitsData {
    var name: String?
}
var secondArray = [fruitsData(name: "apple"),fruitsData(name: "apricot"), fruitsData()]

// [__lldb_expr_98.fruitsData(name: Optional("apple"))]
let flt1 = secondArray.filter { arrayNames.contains($0.name ?? "") }

// [__lldb_expr_87.fruitsData(name: Optional("apricot")), __lldb_expr_87.fruitsData(name: nil)]
let flt2 = secondArray.filter { !arrayNames.contains($0.name ?? "") }