Нужно использовать фильтр в swift для фильтрации внутреннего массива структур, не касаясь внешнего массива - PullRequest
0 голосов
/ 14 мая 2018

Вот игровая площадка, которую я создал, чтобы попытаться создать правильный фильтр: То, что я хочу вернуть, это все внешние структуры и любые внутренние значения массива, которые встречаются с «текстовым» блоком, который будет входить из панели поиска.

//: Playground - noun: a place where people can play

import UIKit
import Foundation

struct events{
    var title:String
    var unique:Int
    var swimmers_info:[swim_info]

}

struct swim_info{
    var name:String
    var team:String
}

var arrayEV:[events]
var si1:[swim_info]
var si2:[swim_info]

si1 = [
    swim_info(name:"Smith, John",team:"PHNX"),
        swim_info(name:"Tenay, Teresa",team:"CRIM")
]

si2 = [
    swim_info(name:"Test, Two",team:"PHNX"),
    swim_info(name:"Female, Swimmer",team:"SSA")
]


arrayEV = [
    events(title: "First Event",unique: 5,swimmers_info:si1),
    events(title: "Second Event",unique: 2,swimmers_info:si2)
]

//print(arrayEV)

var newarrayEV1 = arrayEV.filter({(value) -> Bool in
    return value.swimmers_info.contains(where: {$0.team == "SSA"})
})

var newarrayEV2 = arrayEV.map({$0.swimmers_info.filter({(value) -> Bool in
    return value.team == "SSA"
})})


print(newarrayEV1)

YEILDS [__lldb_expr_42.events (название: «Второе событие», уникальный: 2, swimmers_info: [__lldb_expr_42.swim_info (имя: «Test, Two», команда: «PHNX»), __lldb_expr_42.swim_info (имя: «Женский») Пловец ", команда:" ССА ")])]

** Incorect, потому что он дает только вторую основную структуру и обе подструктуры

print("  ")
print(newarrayEV2   )

[[], [__lldb_expr_42.swim_info (имя: «Женщина, пловец», команда: «SSA»)]]

Неверно, поскольку отбрасывает всю основную информацию о структуре

print("11")

КИНДА ПРАВИЛЬНО

Я могу получить желаемый результат с помощью:

for (index,loop) in arrayEV.enumerated(){
    //print(String(describing: index))
    //print(loop.swimmers_info)
    var new_si = loop.swimmers_info.filter({(value) -> Bool in
        return value.team == "SSA"
    })
    //print(new_si)
    arrayEV[index].swimmers_info = new_si

}

однако я не уверен, что это лучший способ атаковать это.

Ответы [ 2 ]

0 голосов
/ 14 мая 2018

Исходя из предложенного вами "решения", я думаю, что вы ищете:

arrayEV = arrayEV.map {
    var ev = $0
    ev.swimmers_info = ev.swimmers_info.filter {$0.team == "SSA"}
    return ev
}

Причина довольно неуклюжего трехслойного взгляда состоит в том, что мы не можем изменить свойство структуры, если ссылка на саму структуру не является ссылкой var, но map предоставляет нам ссылку let ($0).

0 голосов
/ 14 мая 2018

Создайте метод в вашем event классе, который проверяет текст с внутренним массивом и своим собственным title и сообщает вам, что этот класс относится к match-case или нет

struct events{
    var title:String
    var unique:Int
    var swimmers_info:[swim_info]

    func haveSameText(_ text: String) -> Bool {
        let filtersArray = swimmers_info.filter { (info) -> Bool in
            return info.name.lowercased() == text.lowercased()
        }
        return filtersArray.count >= 0 || text.lowercased() == title.lowercased()
    }
}

struct swim_info{
    var name:String
    var team:String
}

Чтобы отфильтровать массив событий на основе некоторого текста, используйте метод ниже.

var eventArr = [events]()
var filteredArray = eventArr.filter { (event) -> Bool in
    return event.haveSameText("text")
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...