Swift 3 filter array of objects with elements of array
One approach is to update your filter to see if any value in pets is in the petArr
array:
users = users.filter { $0.pets.contains(where: { petArr.contains($0) }) }
The first $0
is from the filter
and it represents each User
.
The second $0
is from the first contains
and it represents each pet within the pets
array of the current User
.
How to filter String array in Swift
Use this code:
let yearArray: [String] = ... // your array of type [String]
let filteredArray = yearArray.filter {
!$0.isEmpty
}
Look at the picture for output:
Swift 4 - Filtering Array with Array
There's nothing wrong with Rakesha Shastri's answer. For performance reasons, you may want to make selectedIDs
a Set
instead of an Array
:
let allEntries = [Entry(id: "1"), Entry(id:"2"), Entry(id:"3"), Entry(id:"4")]
let selectedIDs: Set<String> = ["1", "3"]
let selectedEntries = allEntries.filter({ selectedIDs.contains($0.id) })
The reason is that searching an Array
has a computational complexity of O(n)
where n
is the length of the array, while searching a Set
(i.e. a hash table) is O(1)
on average.
If you keep
selectedIDs
as array, the overall solution has a complexity ofO(n * m)
wheren
andm
are the lengths ofselectedIDs
andallEntries
, respectively.If you use
Set
, the overall complexity reduces toO(m)
.
Having said that, your example is too trivial for either methods to make a difference.
Filter array of strings, including like condition
Use contains
instead:
let arr = ["Hello","Bye","Halo"]
let filtered = arr.filter { $0.contains("lo") }
print(filtered)
Output
["Hello", "Halo"]
Thanks to @user3441734 for pointing out that functionality is of course only available when you import Foundation
How do I filter on an array of objects in Swift?
So I quickly did this to help out, if someone can improve that's fine I'm just trying to help.
I made a struct for the books
struct Book {
let title: String
let tag: [String]
}
Created an array of those
var books: [Book] = []
Which is empty.
I created a new object for each book and appended to books
let dv = Book(title: "The Da Vinci Code", tag: ["Religion","Mystery", "Europe"])
books.append(dv)
let gdt = Book(title: "The Girl With the Dragon Tatoo", tag: ["Psychology","Mystery", "Thriller"])
books.append(gdt)
let fn = Book(title: "Freakonomics", tag: ["Economics","non-fiction", "Psychology"])
books.append(fn)
So you've three objects in the books array now.
Try to check with
print (books.count)
Now you want to filter for Psychology books.
I filtered the array for tags of Psychology - are filters ok for you?
let filtered = books.filter{ $0.tag.contains("Psychology") }
filtered.forEach { print($0) }
Which prints the objects with your two Psychology books
Book(title: "The Girl With the Dragon Tatoo", tag: ["Psychology",
"Mystery", "Thriller"])Book(title: "Freakonomics", tag: ["Economics", "non-fiction",
"Psychology"])
Filtering Array from contents of another Array
With "explicit" return
and no $0
.
let filtered = array2.filter { aString in
return !exclude.contains(where: { anExcludedString in
return aString.range(of: anExcludedString, options: .caseInsensitive) != nil
})
}
Why var filter = array2.filter({exclude.contains($0)})
didn't work?
First issue:
There is no case insensitive check.Second issue:
You are usingcontains()
on a[String]
, not aString
. So it expect full equality between the two strings. So ifarray2
was["APP"]
, it would have worked.
For instance if you had:
let exclude = ["text 1", "text 2", "APP", "John"]
let array2 = ["this is text 1", "This is text 2", "This App is under development", "John is working on this project", "This is great", "This APP is under development"]
let filtered = array2.filter { aString in
return !exclude.contains(where: { anExcludedString in
return aString.contains(anExcludedString)
})
}
Then "This APP is under development"
would have been removed.
Now, going back to the initial answer, the way to check case insentive is to use range(of:options:)
.
Adding a filter to an array in Swift 4
Use filtered.
Here is an example of your unfiltered array
:
var unfilteredItems = ...
Here is a filtering code:
var filteredItems = unfilteredItems.filter { $0.cat == "garden" }
Here is the code:
func loadData() {
items = [Item]()
items = DataManager.loadAll(Item.self).sorted(by: {
$0.createdAt < $1.createdAt }).filter { $0.cat == "garden"}
tableView.reloadData()
}
How to filter array of items by another array of items in swift
Chose 1 in 2 option of return:
func filter(items: [Item], contains tags: [String]) -> [Item] {
items.filter { (item) -> Bool in
let tagNames = item.tags.map({ $0.name })
return tags.allSatisfy(tagNames.contains)
return Set(tags).isSubset(of: Set(tagNames))
}
}
How to filter an array of objects into different segments in Swift
A few things:
First, given that there a finite number of note types, I would model them as an enum instead of a String:
enum NoteType {
case atc
case imaging
case lab
}
You could always add an .unknown
case in the event that your backend provides a String that your client doesn't recognize. It may also be beneficial to give your NoteType
enum a raw type of String and have each rawValue correspond to the values your backend will provide.
Second, it's a bit unclear exactly what you want to accomplish with a UISegmentedControl
. My assumption is that you want a separate segment for each different type of Note? If that's the case, you could make the above enum conform to CaseIterable
and create a segment for each value found in NoteType
's allCases
array. (If you're going the route of having NoteType
s be Strings, then each segment's title could be set to every case's rawValue). It really all depends on what exactly you're trying to accomplish.
Third, I think in the end what you're wanting is three (or however many NoteType
s exist) separate arrays of Notes where each Note
is of the same type. That way you can determine what your UICollectionView
's datasource is depending on which segment of the UISegmentedControl
is selected. If that's what you're wanting (feel free to correct me), you can accomplish that via a simple filter call:
let sortedNotes = associatedNotes.sorted(by: {
$0.date.compare($1.date) == .orderedDescending
})
let atcNotes = sortedNotes.filter { $0.type == .atc }
let imagingNotes = sortedNotes.filter { $0.type == .imaging }
let labNotes = sortedNotes.filter { $0.type == .lab }
Related Topics
Disabling Allowsbackgroundlocationupdates (Cllocationmanager) Doesn't Work After Is Was Enabled
How Is a Swift Cgvector Created with Dx and Dy (Derivative)
Receive Signal from Beacon While App Is in the Background
Nsurlprotocol Isn't Asked to Load After Yes Response to Caninitwithrequest
How to Open Application Using Url
Applying Different Attributes for Different Portions of an Nsattributedstring
Conforming to UItableviewdelegate and UItableviewdatasource in Swift
iPhone - Memory Leak - Nsdata Datawithcontentsofurl & UIwebview
Indexpathforrowatpoint Returns Nil Only for First Cell in a UItableview
No Such Module 'Fbsdkcorekit' Xcode 7.4
How to Fetch Images from Photo Library Within Range of Two Dates in iOS
Notification in Swift Every Day at a Set Time
iOS Where to Put Custom Cell Design? Awakefromnib or Cellforrowatindexpath
Objc Protocol Implementation in Swift
Dateformatter Gives Wrong Time on Conversation
How to Draw a Uilabel with a Different Blend Mode in Draw(_ Rect: Cgrect) in Swift