Как отфильтровать массив словарей в Swift - PullRequest
0 голосов
/ 29 сентября 2018

Я решил заполнить NSTableview, используя изменяемый массив объектов словаря, где ключ словаря - это идентификатор столбца, а значение - значение столбца.Я заполняю массив следующим образом:

var compArray: NSMutableArray = []

let dict = ["idCompany": id, "company": companyName, "compType": 
companyType] as [String : Any]
            compArray.add(dict)

id, company и compType происходят из запроса SQlite.

Я использую compArray в качестве источника данных tableView.Это прекрасно работает.Контроллер массива не задействован.

Таблица загружается следующим образом с использованием CDM, который является экземпляром класса, который предоставляет compArray

//Define the function that will get the data for each cell for each 
//row.
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {

    //Define constant dict as an NSDictionary and set to the DM 
    //instance of the DataModel class at the row being loaded into the 
    //table. DM needs to be cast as an NSDictionary. row is passed in as a 
    //parameter by the OS
    let tdict:NSDictionary = CDM.compArray[row] as! NSDictionary

    //Define strKey as the column identifier for the column being 
    //loaded. Column being loaded is passed in as a parameter by the OS
    let strKey = (tableColumn?.identifier)!

    //method will return the value from dict (which is loaded from 
    //CDM.compArray) for the key that is equal to the column identifier 
    //which was loaded to strKey
    return tdict.value(forKey: strKey.rawValue)
}

Что я хотел бы сделать, это ввести NSSearchполе для поиска во всех столбцах таблицы.

Я добавил поле поиска в качестве действия и добавил код для хранения compArray в копию с именем backupCompArray.

Я определил переменную isSearching:

//The variable is set to true when searching
var isSearching = false {
    //This will be fired if the state of isSearching changes ie false 
    //to true or true to false
    didSet {

        //Test to see whether isSearching now has a new value and if 
        //so we do the housekeeping
        if isSearching != oldValue {

            //If isSearching is now true then it must have previously 
            //been false and we now need to back up the original array
            if isSearching {
                //Back up the original array
                backUpCompArray = compArray
            } else{
                //It is now turning from true to false so need to 
//restore
                compArray = backUpCompArray
            }
        }
    }
}

Я хочу иметь возможность фильтровать compArray на основе .stringValue поля поиска.

Я добавил следующее в @IBAction поля поиска:

@IBAction func searchField(_ sender: NSSearchFieldCell) {
    if sender.stringValue.isEmpty {
        //If stringValue is empty then cant be searching and this can 
        //trigger the restore of the original array
        isSearching = false
    } else {

        //If stringValue is not empty then must be searching. When the 
        //search starts need to backup the original array
        isSearching = true

        //?????????????
        }
    }

    tableView.reloadData()
}

Мне нужно заменить?с кодом, который может устанавливать compArray, применяя фильтр к backupCompArray, возвращая любые строки в compArray, где значения словаря для ключей "company" и "compType" содержат searchfield.Stringvalue.Затем я могу использовать модифицированный compArray для загрузки таблицы только с отфильтрованными строками.

Итак, я попробовал ваш код и получил две ошибки, которые я пытался исправить следующим образом:

//Can use the .filter method it will iterate each value in the array
        CDM.compArray = backupCompArray.filter(using: {
            // this is where you determine whether to include the 
specific element, $0
            $0["company"]!.contains(sender.stringValue) &&
            $0["compType"]!.contains(sender.stringValue)
            // or whatever search method you're using instead
        })
    }

То естьвставив 'using' и изменив searchString на sender.Stringvalue.

Но теперь я получаю: enter image description here

против строки, заканчивающейся на &&

1 Ответ

0 голосов
/ 29 сентября 2018

Вы можете сделать это с помощью Swift 4's Array.filter().Требуется функция, в которой вы можете выполнять вычисленияНа самом деле вам не нужно создавать резервную копию вашего compArray, если только вам не понадобится хранить его позже для чего-то другого.

compArray = compArray.filter({
    // this is where you determine whether to include the specific element, $0
    $0["company"]!.contains(searchString) &&
    $0["compType"]!.contains(searchString)
    // or whatever search method you're using instead
})
...