代码之家  ›  专栏  ›  技术社区  ›  Martin Muldoon

遍历数组以查找值对

  •  1
  • Martin Muldoon  · 技术社区  · 6 年前

    我有一个排序数组。我希望遍历数组,并在找到成对的值时递增计数器。我没有找到一个优雅的解决方案。

    var pairs = 0
        let colors = [10, 20, 20, 10, 10, 30, 50, 10, 20
        let sortedColors = colors.sorted{ $0 < $1}
        // [10, 10, 10, 10, 20, 20, 20, 30, 50] -> pairs should equal 3
    
        for i in 0..<colors.count - 1 {
            if sortedColors[i+1] != colors.count && sortedColors[i] == sortedColors[i+1] {
                pairs += 1
            } 
        }
    
    print(pairs)
    
    3 回复  |  直到 6 年前
        1
  •  3
  •   Sandeep    6 年前

    你也可以像这样使用新的字典语法,

    使用分组语法,

    let pairs = Dictionary(grouping: colors){ $0 }
                            .map { $1.count / 2 }
                            .reduce(0, +)
    print(pairs)
    

    使用uniquing语法,

    let pairs = Dictionary( zip( colors, Array(repeating: 1, count: colors.count)),
                           uniquingKeysWith: +)
                          .reduce(0, { $0 + $1.1 / 2})
    
        2
  •  2
  •   dfrib    6 年前

    一种替代方法,但类似于 @Sulthan's answer 是使用字典计算发生次数,而不是 NSCountedSet :

    let colors = [10, 20, 20, 10, 10, 30, 50, 10, 20]
    let numberOfPairs = colors
      .reduce(into: [:]) { counts, num in counts[num, default: 0] += 1 }
      .reduce(0) { cumsum, kv in cumsum + kv.value / 2 } // 3
    

    或者,在两个闭包中使用速记参数名称:

    let numberOfPairs = colors
      .reduce(into: [:]) { $0[$1, default: 0] += 1 }
      .reduce(0) { $0 + $1.value / 2 }
    

    其中,对于次数发生计数,我们使用 @vacawama's answer 在问答中;我最初将其用作重复标记此问题的目标(&A.

        3
  •  2
  •   Sulthan    6 年前

    我只需计算重复次数,然后将重复次数除以2来计算成对数。例如,如果一个数字出现3次,则有一对:

    let colors = [10, 20, 20, 10, 10, 30, 50, 10, 20]
    
    let countedSet = NSCountedSet(array: colors)
    let pairs = countedSet.map { countedSet.count(for: $0) / 2 }.reduce(0, +)
    print(pairs) // 3
    

    不幸的是,没有Swift CountedSet 然而:(