【问题标题】:How To Filter Array Using Element in Another Array in Swift?如何在 Swift 中使用另一个数组中的元素过滤数组?
【发布时间】:2015-12-31 18:01:52
【问题描述】:

我有两个数组

let toBeFiltered = ["star0", "star2", "star1", "star0", "star3", "star4"]
let theFilter = ["star1", "star3"]

如何使用第二个数组过滤第一个数组?实际上 theFilter 可以动态更改,例如,

let theFilter = ["star2"]
or maybe
let theFilter = ["star0", "star4", "star2"]

感谢您的帮助:)

【问题讨论】:

    标签: ios arrays filter swift2


    【解决方案1】:

    使用设置操作

    Set(toBeFiltered).intersection(Set(theFilter))
    

    阅读更多:https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/CollectionTypes.html

    【讨论】:

    • 精彩的解释!我一直在使用SetNSCountedSet,但这似乎可以用更少的代码行做很多相同的事情。
    【解决方案2】:
    let toBeFiltered = ["star0", "star2", "star1", "star0", "star3", "star4"]
    let theFilter = ["star1", "star3"]
    
    let filtered = toBeFiltered.filter(theFilter.contains)
    

    【讨论】:

    • 这很好但是我怎样才能得到过滤器的索引来过滤另一个基于这个数组的数组呢?
    • 试试这样的let array = [1, 3, 8, 6, 4, 3] let filtered = toBeFiltered.enumerated().filter { $0.offset == $0.element }.map { $0.element }
    【解决方案3】:

    你也可以过滤结构数组

    struct myStruct
            {
              var userid:String;
              var details:String;
              init() {
                userid = "default value";
                details = "default";
              }
    
        };
        var f1 = myStruct();
        f1.userid = "1";
        f1.details = "Good boy";
    
        var f2 = myStruct();
        f2.userid = "2";
        f2.details = "Bad boy";
    
        var f3 = myStruct();
        f3.userid = "3";
        f3.details = "Gentleman";
    
        var arrNames1:Array = [f1,f3];
    
        var arrNames2:Array = [f3,f1,f2];
    
        let filteredArrayStruct =  arrNames1.filter( { (user: myStruct) -> Bool in
          return arrNames2.contains({ (user1: myStruct) -> Bool in
            return user.userid == user1.userid;
          })
        })
    print(filteredArrayStruct)
    

    对于 Set 你必须遵守 Hashable 协议

    class mytestclass: Hashable
    {
      var userid:Int ;
      var details:String;
    
      var hashValue: Int {
        return self.userid
      }
      init(userid: Int, details:String)
     {
      self.userid = userid;
      self.details = details;
      }
    }
    func ==(lhs: mytestclass, rhs: mytestclass) -> Bool {
      return lhs.userid == rhs.userid
    }
    
    var t1 = mytestclass(userid: 1,details: "Good boy");
    
    
    var t2 = mytestclass(userid: 2,details: "bad boy");
    
    var t3 = mytestclass(userid: 3,details: "gentle man");
    
    
    var classArrayNames:Set<mytestclass> = [t1,t2];
    
    var classArrayNames2:Set<mytestclass> = [t3,t1,t2];
    
    
     let result =  Set(classArrayNames).intersect(classArrayNames2)
    

    【讨论】:

      【解决方案4】:

      这似乎是今天的主题 :) 基于另一个很好的答案,我建议在 Set 上使用 intersect(_:) 方法:

      let toBeFiltered = ["star0", "star2", "star1", "star0", "star3", "star4"]
      let theFilter = ["star1", "star3"]
      let filtered = Set(toBeFiltered).intersect(theFilter)
      
      // => ["star1", "star3"] of type Set<String>
      
      // ...if you actually need an array, you can get one using Array(filtered)
      

      【讨论】:

        【解决方案5】:

        虽然使用 Arsen 提出的 Sets 无疑是最优雅的,但有时您希望保持 duplicatesorder

        //: Playground - noun: a place where people can play
        
        import Foundation
        
        extension Collection where Element: Equatable {
        
            func intersection(with filter: [Element]) -> [Element] {
                return self.filter { element in filter.contains(element) }
            }
        
        }
        
        let toBeFiltered = ["star0", "star2", "star1", "star0", "star3", "star4", "star1"]
        let theFilter = ["star1", "star3"]
        
        let filtered = toBeFiltered.intersection(with: theFilter) // ["star1", "star3", "star1"]
        

        【讨论】:

          【解决方案6】:
          let mainArray = ["one", "two", "three", "three", "three", "four", "five"]
          let miniArray = ["two", "three"]
          let leftOvers = mainArray.filter( {miniArray.contains($0) == false} )
          print(leftOvers)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-02-26
            • 1970-01-01
            • 1970-01-01
            • 2016-04-26
            • 1970-01-01
            • 1970-01-01
            • 2015-12-14
            • 2019-01-03
            相关资源
            最近更新 更多