Как найти определенную строку в массиве объектов, просматривая каждый объект в Swift? - PullRequest
0 голосов
/ 10 октября 2018

Я установил массив объектов различных типов (3 объекта, содержащие String, Double, String, Double)

И я ищу для поиска первый индекс в массиве, который возвращает "Конкретная строка ".

Как мне сделать это по-быстрому?
Я пробовал .contains, .indexOf, .first, и все они продолжают давать мне ошибки

Ошибки:

Невозможно преобразовать значение типа 'String' в ожидаемый тип аргумента '( myvalue ) throws -> Bool'
Невозможно преобразовать значение типа ' Myobject 'к ожидаемому типу аргумента ... и т. Д.)

Любые полезные идеи или информация будут благословением.

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

Предположим, что ваши объекты определены следующим образом:

struct MyObject {
    let firstString: String
    let firstDouble: Double
    let secondString: String
    let secondDouble: Double
}

Давайте определим три объекта:

let firstObject = MyObject(firstString: "uno",
                           firstDouble: 1,
                           secondString: "un",
                           secondDouble: 11)
let secondObject = MyObject(firstString: "dos",
                           firstDouble: 2,
                           secondString: "deux",
                           secondDouble: 22)
let thirdObject = MyObject(firstString: "uno",
                           firstDouble: 3,
                           secondString: "deux",
                           secondDouble: 33)

И поместим их в массив:

let myArray: [MyObject] = [firstObject, secondObject, thirdObject]

Вы можете получить первый элемент со свойством firstString, равным "uno", используя first(where:):

let firstUno: (Int, MyObject)? = myArray
    .enumerated()
    .first(where: { $0.1.firstString == "uno"})

if let uno = firstUno {
    print("First uno index =", uno.0)  //First uno index = 0
    print("First uno object =", uno.1) //First uno object = MyObject(firstString: "uno", firstDouble: 1.0, secondString: "un", secondDouble: 11.0)
}

Вы можете сделать то же самое, чтобы получить первый объектсвойство secondString которого равно "deux":

let firstDeux: (Int, MyObject)? = myArray
    .enumerated()
    .first(where: { $0.1.secondString == "deux"})

if let deux = firstDeux {
    print("First deux index =", deux.0)  //First deux index = 1
    print("First deux object =", deux.1) //First deux object = MyObject(firstString: "dos", firstDouble: 2.0, secondString: "deux", secondDouble: 22.0)
}
0 голосов
/ 10 октября 2018

Как правило, не рекомендуется иметь массивы разнородных (множественных) типов.С ними обычно довольно сложно работать, и вы столкнулись с одной из ловушек.

Варианты Collection.firstIndex(of:), Sequence.contains(_:),и т.д., которые вы ищете, это те, которые условно определены только тогда, когда тип элемента является уравниваемым.Даже если все упомянутые вами типы Equatable, предполагаемый тип массива - Array<Any>.Any не является Equatable, поэтому ваш массив не является кандидатом на эти функции.

Вместо этого вам придется использовать функции, основанные на предикатах.Они принимают предикат типа (Element) -> Bool.Каждый элемент передается в предикат в качестве аргумента параметра типа Element, и ваша задача - вернуть true, если элемент соответствует вашему предикату, и false, если это не так.Например, index(where:) вернет индекс первого элемента, который возвращает предикат true.Например:

let stuff: [Any] = [1, false, "abc"]
if let abcIndex = stuff.index(where: { $0 == "abc" }) {
    print("Found \"abc\" at index \(abcIndex)")
}

К сожалению, Equatable - это протокол со связанным типом.Это как шаблон, который может описывать типы, но сам по себе это не номинальный тип.Таким образом, вы не можете сейчас делать что-то вроде:

let equatableStuff: [Equatable] = [1, false, "abc"]
if let abcIndex = stuff.index(of: "abc") {
    print("Found \"abc\" at index \(abcIndex)")
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...