I am trying to filter my dictionary according to user input in UISearchController. I have following model and array of objects.
struct People {
var name: String
var id: Int
}
let first = People(name: "Atalay", id: 1)
let second = People(name: "Ahmet", id: 2)
let third = People(name: "Mehmet", id: 3)
let fourth = People(name: "Yusuf", id: 4)
let peoples: [People] = [first, second, third, fourth, fifth]
I put them into a dictionary to create section indexed table view with following code.
var dict: [String: [People]] = Dictionary(grouping: peoples, by: { (people) -> String in
return String(people.name.prefix(1))
})
Above code gives me a dictionary with first letter of People names. Now, I would like to filter my array according to user input. However, I tried following code for filtering but it is not working as I expected.
let filteredDict = (dict.filter { $0.1.contains { $0.name.lowercased().contains("ata") } })
It returns all "A" letter section indexes like ["A": People(name: "Atalay", id: 1), People(name: "Ahmet", id: 2)]
How can I achieve filter also my array inside dictionary?
If I'm not mistaken, you want your final dictionary to have all the keys and only the filtered array of items as the values. If that is right, reduce is the tool for that:
let filtered = dict.reduce(into: [String: [People]]()) {
$0[$1.key] = $1.value.filter { $0.name.lowercased().contains("ata") }
}
I decided it was simplest to get this right by using an old fashioned for loop and filter each group separately
var filtered = [String: [People]]()
for (k, v) in dict {
let result = v.filter {$0.name.lowercased().contains("ata")}
if result.count > 0 {
filtered[k] = result
}
}
Note that if you want to keep all the groups in the result dictionary just skip the if result.count > 0 condition
How can I achieve filter also my array inside dictionary?
You should have an array first, you can use flatMap to group all the values in your filteredDict
let array = filteredDict.flatMap { $0.value }
Then you just filter the array as usually
let filteredArray = array.filter { $0.name.lowercased().contains("ata") }
By using objective C I have filter year array by using NSPredicate,
Below is code.
yearArray = [yearArray filteredArrayUsingPredicate:[NSPredicate
predicateWithFormat:#"SELF != ''"]];
As per above code it's working fine in objective c , I have to filter array in Swift 3,
What is Input Year Array :-
( Year,"","","",JAN,"","","",FEB,"","","",MAR,"","","",APR,"","","",
MAY,"","","",JUN,"","","",JUL,"","","",AUG,"","","",SEP,"","","",OCT
,"","","", NOV,"","","",DEC,"","","","",WIN,"","","",SPR,"","","",SUM
,"","","",AUT,"","","","",ANN)
Need filter Output Array
(Year,JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC,WIN,SPR,SUM,AUT,ANN)
Please give solution how to filter 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:
You can do it by using filter (on an Array type) :
let filteredArray = yearArray.filter{$0 != ""}
It's that simple.
If your array is an NSMutableArray, just cast it to [String] :
if let yearArray = yearArray as? [String] {
let filteredArray = yearArray.filter{$0 != ""}
// add your code here
}
I have a fullName property in my Core Data entity Friends, which has values like:
John Doe
Jane Smith
Joe Bloggs
I want to be able to extract the last name, and sort using these alphabetically, in Swift.
I currently only know how to sort using the full name, like so:
let sortDescriptor = NSSortDescriptor(key: "fullName", ascending: true)
request.sortDescriptors = [sortDescriptor]
Thanks.
You can do as Follow.
1) Fetch all record from core data. (Suppose You have get aryFullname)
2) Using for loop you can get array only last name as follow.
//Define new mutable array aryfinalData
for i in 0..<aryFullname.count
{
var fullName = aryFullname.ObjectAtindex(i)
var fullNameArr = split(fullName) {$0 == " "}
var lastName: String? = fullNameArr.count > 1 ? fullNameArr[1] : nil
aryfinalData.addObject(lastName)
}
3) Sort Array as follow.
// convert NSMutableArray to the Array by using below line of code.
let arySort = aryfinalData as AnyObject as! [String]
var sortedArray = arySort.sort { $0.name < $1.name }
// sortedArray is your Final array
Note: This is not a efficient solution but you don't have any solution and I am not sure about the above syntax so take care for the same and do changes if any require.
I have store the contact in alphabetical order so I have array of array for contact list which i have display on screen. Now i want to search the contact via name but predicate not work properly here. I have done below code.
filterArray.filterUsingPredicate(NSPredicate(format: "ANY SELF.name CONTAINS[cd] '\(tfSearchBar.text!)'", argumentArray: nil))
In filter array first i have all contact but when i search for "a" it gives all the section array which has "a" in the contact name. but here i have stuck. It is not necessary that the all contact of the section contain "a" in the contact name.
For example
(
A:(
{
name = "abc"
number = "123456"
}
{
name = "azx"
number = "123456"
}
)
)
For example for above example after search for "a". when i search for "ab" then same array return by predicate.Not only first object. Any way to find only first object with out nested predicate.
I'm not sure what you are trying to accomplish with the word "ANY" in your predicate but it seems redundant. This code works as you describe when put into a Playground:
import UIKit
#objc class DataElement : NSObject {
let name : String
let number : String
init(name : String, number : String) {
self.name = name
self.number = number
}
}
let dataArray : NSArray = [
DataElement(name: "abc", number: "123456"),
DataElement(name: "azx", number: "689101")
]
let searchTerm = "a"
let predicate = NSPredicate(format: "SELF.name CONTAINS[cd] '\(searchTerm)'", argumentArray: nil)
dataArray.filteredArrayUsingPredicate(predicate)
In my app I have got hundreds of movie objects as CKRecords that is being put in an array after retrieving them. I would, for example, like a way to check if the array contains a movie record with the title "Titanic".
What I have done up till now, is looping trough the array like this:
for movie in (movies as NSArray as! [CKRecord]) {
if movie.objectForKey("Title") as? String == "Titanic" {
// Do stuff
}
}
But what I want is something like this:
if movies.contains(CKRecord.whereKey"Title" == "Titanic") {
// Do stuff
}
You have to use a filter in the array, for example:
let filteredArray = movies.filter() {
if let title = ($0 as PFObject)["Title"] as String {
return type.rangeOfString("example") != nil
} else {
return false
}
}
There are 2 ways we can proceed with this:
1 Approach: Using NSpredicate
let predicate = NSPredicate(format: "Title = 'Titanic'")
let movie = (movies as NSArray).filteredArrayUsingPredicate(predicate) as! NSArray
Then we can check the count of array for presence of object.
Using Filter function as give by #Exequiel above