Как найти первый индекс элемента в массиве массивов

#ios #arrays #swift

Вопрос:

У меня есть массив массивов, таких как

 var arr = [[("aa",1),("b",2)],[("c",3),("dd",4)],[("e",5),("f",6)]]
 

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

 let val = arr.first(where: {$0.1 == "dd" })
 

Ответ №1:

Вы использовали multi-dimensional arrays , пожалуйста, уточните, какой индекс вы ищете(внутренний/внешний индекс).

В случае, если вы имеете в виду индекс внешнего массива:

 let outerIndex = arr.firstIndex(where: { $0.contains(where: { $0.0 == "dd"}) })
 

В случае, если вы имеете в виду внутренний индекс массива:

 let innerIndex = arr.map({ $0.firstIndex(where: { $0.0 == "dd" }) }).filter({ $0 != nil }).first
 

В случае, если вам нужны оба индекса:

 var bothIndex: (outer: Int?, inner: Int?) {
    guard let outerIndex: Int = arr.firstIndex(where: { $0.contains(where: { $0.0 == "dd"}) }) else {
        assertionFailure()
        return (nil,nil)
    }
    
    let innerIndex: Int? = arr[outerIndex].firstIndex(where: { $0.0 == "dd"})
    return (outerIndex, innerIndex)
}
 

Ответ №2:

Во-первых, кортежи индексируются с 0, так что это должно быть $0,0, и чтобы найти индекс, который вам нужно использовать firstIndex , и, наконец, поскольку у вас есть массив массивов, вам нужно перейти на один уровень, а затем вернуться, когда у вас есть совпадение во внутреннем массиве, я использую contains для внутренних массивов

 let val = arr.firstIndex(where: { 
    $0.contains(where: { tuple in tuple.0 == "dd" })
})
 

Комментарии:

1. отличный ответ, я возился с вопросом и думал, что почти понял его, но, думаю, я был далек от этого ответа :]

Ответ №3:

Из вашего кода следует, что у вас есть значение для каждой буквы, например, «aa» имеет 1, «b» имеет 2 и так далее.

Если вы хотите найти значение, соответствующее «dd», я бы посоветовал вам использовать хэш-карты/Словарь !!

Таким образом, ваш код будет

    var values = ["aa":1, "b":2, "c":3, "dd":4, "e":5, "f":6]
   let val = values["dd"] //val = 4
 

Комментарии:

1. Хотя использование словаря вместо массива кортежей, безусловно, является хорошим решением, вам не хватает того, что у OP есть массив массивов с кортежами, поэтому вы теряете внутренний массив с этим ответом.

2. что вы подразумеваете под операцией ?? Извините, я ответил на этот вопрос, потому что думал, что с помощью словаря будет намного проще

3. OP-это аббревиатура, часто используемая в Интернете для обозначения парня, который задал вопрос или начал дискуссию, OP = Оригинальный плакат. Как я уже упоминал, здесь словарь на самом деле не работает, так как он представляет собой массив массивов, и поэтому данные сгруппированы вместе.

4. оооо!! мой плохой , извините и спасибо @JoakimDanielson!!

Ответ №4:

val будет в этом случае вторым внутренним массивом. Первый внутренний массив, содержащий «dd»

 let val = arr.first(where: { $0.first(where: { $0.0 == "dd" }) != nil } )
 

Ответ №5:

У вас есть массив массивов. Вам понадобится индекс как внешнего, так и внутреннего массива:


 var arr = [[("aa",1),("b",2)],[("c",3),("dd",4)],[("e",5),("f",6)]]

let predicate: ((String,Int)) -> Bool = { $0.0 == "dd" }
if let index = arr.firstIndex(where: {$0.contains(where: predicate)}),
    let subIndex = arr[index].firstIndex(where: predicate) {
    print(arr[index][subIndex])  // ("dd", 4)
}
 

Развивая эту тему:

 extension Collection where Element: Collection {
    func firstIndexAndSubIndex(where predicate: (Element.Element) -> Bool) -> (index: Index, subIndex: Element.Index)? {
        if let index = firstIndex(where: {$0.contains(where: predicate)}),
            let subIndex = self[index].firstIndex(where: predicate) {
            return (index,subIndex)
        }
        return nil
    }
}
 

использование:

 var arr = [[("aa",1),("b",2)],[("c",3),("dd",4)],[("e",5),("f",6)]]

if let idxs = arr.firstIndexAndSubIndex(where: { $0.0 == "dd" } ) {
    print(arr[idxs.index][idxs.subIndex])  // ("dd", 4)
}