如何从两个元素列表中获取元组

时间:2019-02-04 17:03:14

标签: arrays swift for-loop tuples

我有两个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 :(得分:1)

制作一个字典,用它们的ID为两个视图列表建立索引,过滤掉ID为零的视图,然后使用两个字典共有的键来创建一个新的字典,以对相同ID的视图进行索引。 >

这是一个粗略的例子(我自己还没有编译)。

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)时间,这是解决此问题的最佳方法。

答案 1 :(得分:0)

我认为您应该首先从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)
    }
}
}

答案 2 :(得分:0)

此解决方案创建一个元组数组,分别具有来自第一个列表和第二个列表的视图

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))})
    }
})