2015-07-07 3 views
4

Удивление, если кто-то может помочь мне с фильтрацией с использованием предикатов в Swift.Swift: Фильтрация массива структур с использованием UISearchController/Predicates

У меня есть несколько грязный источник данных, который я использую для заполнения UITableView. Источником данных является массив структур. Структура определяется следующим образом:

struct Exercises { 
    let category: String 
    let name : String 
    let x_seed: [Double] 
    let y_seed: [Double] 
    let hasMult: Bool 
} 

Теперь в моем контроллере Tableview я держу массив структур, содержащий все данные для таблицы.

class MainTableViewController: UITableViewController, UISearchResultsUpdating { 


var exercises = [Exercises]() 
var filtered_exercises = [Exercises]() 
var resultSearchController = UISearchController() 

override func viewDidLoad() { 
    super.viewDidLoad() 

    // MARK: - Table view data source 
    self.exercises = [ 
     Exercises(category:"Sports", name:"Bowling", x_seed:[125,155,185], y_seed:[3.00, 3.73, 4.43], hasMult:false), 
     Exercises(category:"Sports", name:"Water Polo", x_seed:[125,155,185], y_seed:[10.00, 12.40,14.80], hasMult:false), 
     Exercises(category:"Sports", name:"Handball", x_seed:[125,155,185], y_seed:[12.00, 14.87, 17.77], hasMult:false), 
     Exercises(category:"Sports", name:"Dancing", x_seed:[125,155,185], y_seed:[3.00, 3.73, 4.43], hasMult:true), 
     Exercises(category:"Sports", name:"Frisbee", x_seed:[125,155,185], y_seed:[3.00, 3.73, 4.43], hasMult:false), 
     Exercises(category:"Sports", name:"Volleyball", x_seed:[125,155,185], y_seed:[3.00, 3.73, 4.43], hasMult:false), 
     Exercises(category:"Sports", name:"Archery", x_seed:[125,155,185], y_seed:[3.50, 4.33, 5.17], hasMult:false), 
     Exercises(category:"Sports", name:"Golf", x_seed:[125,155,185], y_seed:[3.50, 4.33, 5.17], hasMult:true)] 

    self.resultSearchController = ({ 
     let controller = UISearchController(searchResultsController: nil) 
     controller.searchResultsUpdater = self 
     controller.dimsBackgroundDuringPresentation = false 
     controller.searchBar.sizeToFit() 

     self.tableView.tableHeaderView = controller.searchBar 

     return controller 
    })() 

    self.tableView.reloadData() 
} 

То, что я хотел бы сделать, это ФИЛЬТР ДЛЯ упражнения массива на основе поля «имя» и заполнить новую DataSource filtered_exercises заполнить TableView. Я не уверен, как обернуть голову тем, как использовать предикаты в этой ситуации.

// Search functionality 
func updateSearchResultsForSearchController(searchController: UISearchController) 
{ 
    filtered_exercises.removeAll(keepCapacity: false) 

    let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text!) 
    // ?????????????? 

    self.tableView.reloadData() 
} 

Я знаю, что могу читать все имена в строковом массиве и легко отображать это в табличном представлении. Проблема в том, что мне нужно сохранить структуры, поскольку содержащиеся там данные передаются на другие контроллеры представлений.

Итак, как я могу отфильтровать массив структур?

Спасибо!

ответ

3

Если вы не настаиваете на NSPredicate (не вижу причин, почему вы должны, так как вы не используете NSFetchRequest ...), вот код:

struct Exercises { 
    let category: String 
    let name : String 
    let x_seed: [Double] 
    let y_seed: [Double] 
    let hasMult: Bool 
} 

let exercises = [ 
    Exercises(category:"Sports", name:"Bowling", x_seed:[125,155,185], y_seed:[3.00, 3.73, 4.43], hasMult:false), 
    Exercises(category:"Sports", name:"Water Polo", x_seed:[125,155,185], y_seed:[10.00, 12.40,14.80], hasMult:false), 
    Exercises(category:"Sports", name:"Handball", x_seed:[125,155,185], y_seed:[12.00, 14.87, 17.77], hasMult:false), 
    Exercises(category:"Sports", name:"Dancing", x_seed:[125,155,185], y_seed:[3.00, 3.73, 4.43], hasMult:true), 
    Exercises(category:"Sports", name:"Frisbee", x_seed:[125,155,185], y_seed:[3.00, 3.73, 4.43], hasMult:false), 
    Exercises(category:"Sports", name:"Volleyball", x_seed:[125,155,185], y_seed:[3.00, 3.73, 4.43], hasMult:false), 
    Exercises(category:"Sports", name:"Archery", x_seed:[125,155,185], y_seed:[3.50, 4.33, 5.17], hasMult:false), 
    Exercises(category:"Sports", name:"Golf", x_seed:[125,155,185], y_seed:[3.50, 4.33, 5.17], hasMult:true) 
] 

let options = NSStringCompareOptions.CaseInsensitiveSearch | NSStringCompareOptions.DiacriticInsensitiveSearch 

// Filter exercises by name (case and diacritic insensitive) 
let filteredExercises = exercises.filter { 
    $0.name.rangeOfString("Ol", options: options) != nil 
} 

let filteredExerciseNames = ", ".join(filteredExercises.map({ $0.name })) 
println(filteredExerciseNames) 

Он печатает Водное поло , Волейбол, Гольф.

+1

Это хорошее начало. Однако он возвращает массив строк для имен. В идеале я мог бы фильтровать массив структуры по именам и возвращать массив структур отфильтрованных результатов. Это возможно? Если нет, я, вероятно, смогу выполнить эту работу. Благодаря! – 0000101010

+1

Это там, проверьте filterEcercises массив, это [Упражнение] array :) filtersEcercisesNames просто для демонстрации, что он работает. – robertvojta

+0

О, ох ... Я не знаю, как я это пропустил. Ну, спасибо, это работает отлично! Приветствия. – 0000101010

Смежные вопросы