24

I have two arrays

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

How to filter the first array using the second array? Actually the theFilter can be changed dynamically, e.g,

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

Thanks for your help :)

6 Answers 6

73

Use Set Operations

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

Read more: https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/CollectionTypes.html

Sign up to request clarification or add additional context in comments.

1 Comment

Fantastic explanation! I had been using Set and NSCountedSet, but this seems like it'll do a lot of the same stuff with fewer lines of code.
16
let toBeFiltered = ["star0", "star2", "star1", "star0", "star3", "star4"]
let theFilter = ["star1", "star3"]

let filtered = toBeFiltered.filter(theFilter.contains)

2 Comments

this is nice But how can I get the index of filter to filter another array base on this array ?
Try something like this let array = [1, 3, 8, 6, 4, 3] let filtered = toBeFiltered.enumerated().filter { $0.offset == $0.element }.map { $0.element }
11

You can also filter Struct array as well

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)

For Set you must conforms the Hashable protocol

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)

Comments

9
let mainArray = ["one", "two", "three", "three", "three", "four", "five"]
let miniArray = ["two", "three"]
let leftOvers = mainArray.filter( {miniArray.contains($0) == false} )
print(leftOvers)

Comments

6

this seems to be a theme today :) building on another great answer, I would suggest using the intersect(_:) method on a Set:

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)

Comments

5

While using Sets as proposed by Arsen is definitly most elegant, sometimes you want to keep duplicates and order:

//: 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"]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.