Как получить кортеж из двух списков элементов - PullRequest
0 голосов
/ 04 февраля 2019

У меня есть два списка UIViews, некоторые из которых UIViews имеют accessibilityIdentifier, большинство из которых nil.Я ищу способ создать кортеж (или что-то) с двумя UIViews из списков, которые имеют одинаковые accessibilityIdentifier.

Списки не отсортированы или что-то.

Есть ли способ не повторять несколько раз второй список, чтобы найти каждую пару?

for view in firstViewList {
   if view.accessibilityIdentifier != nil {
       for secondView in secondViewList {
           if secondView.accessibilityIdentifier != nil && secondView.accessibilityIdentifier == view.accessibilityIdentifier {
               viewPairs.append((firstView: view, secondView: secondView))
           }
       }
   }
}

Я думаю, что это не очень эффективно.

Ответы [ 3 ]

0 голосов
/ 04 февраля 2019

Создайте dict, который индексирует оба списка представлений по их идентификатору, отфильтруйте те, где ID равен nil, и затем используйте ключи, общие для обоих, для создания нового dict, который индексирует пары представлений с одинаковым идентификатором.

Вот грубый пример (который я сам не скомпилировал).

func makeDictByAccessibilityID(_ views: [UIView]) -> [AccessibilityID: UIView] {
    return Dictionary(uniqueKeysWithValues:
        firstViewList
            .lazy
            .map { (id: $0.accessibilityIdentifier, view: $0) }
            .filter { $0.id != nil }
    )
}

viewsByAccessibilityID1 = makeDictByAccessibilityID(firstViewList)
viewsByAccessibilityID2 = makeDictByAccessibilityID(secondViewList)
commonIDs = Set(viewsByAccessibilityID1.keys).intersecting(
                Set(viewsByAccessibilityID2.keys)
            )

let viewPairsByAccessibilityID = Dictionary(uniqueKeysWithValues:
    commonIDs.lazy.map { id in
        // Justified force unwrap, because we specifically defined the keys as being available in both dicts.
        (key: id, viewPair: (viewsByAccessibilityID1[id]!, viewsByAccessibilityID2[id]!))
    }
}

Это выполняется за O (n) раз, что является лучшим, что вы можете получить для этой проблемы.

0 голосов
/ 04 февраля 2019

Это решение создает массив кортежей с представлениями из первого и второго списка соответственно

var viewArray: [(UIView, UIView)]
firstViewList.forEach( { view in
    if let identifier = view.accessibilityIdentifier {
       let arr = secondViewList.filter( {$0.accessibilityIdentifier == identifier} )
        arr.forEach( { viewArray.append((view, $0))})
    }
})
0 голосов
/ 04 февраля 2019

Я думаю, вам следует сначала отфильтровать два массива по значению nil, затем вы можете сделать это следующим образом

let tempfirstViewList = firstViewList.filter { (view) -> Bool in
view.accessibilityIdentifier != nil
}
var tempsecondViewList = secondViewList.filter { (view) -> Bool in
view.accessibilityIdentifier != nil
}
tempfirstViewList.forEach { (view) in
let filterdSecondViewList = tempsecondViewList.filter { (secondView) -> Bool in
     secondView.accessibilityIdentifier == view.accessibilityIdentifier
}
if let sView = filterdSecondViewList.first {
    viewPairs.append((firstView: view, secondView: sView))
//after add it to your tuple remove it from the temp array to not loop throw it again
    if let index = tempsecondViewList.firstIndex(of: sView) {
        tempsecondViewList.remove(at: index)
    }
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...