You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何在多维数组上使用reduce()?实现元素两两双向对比计数及报错解决

解决多维数组双向两两对比计数的问题

咱们先理清你用reduce()时报错的核心原因,再一步步实现你要的双向两两对比需求~

为什么你的reduce()代码报错?

你第一次使用reduce()时,犯了一个常见误解:reduce闭包里的$0是累加器(你传入的初始值是0,类型为Int),而非数组里的元素!所以你试图对Int类型的$0使用下标[0]、[1],自然会报“Value of type 'Int' has no subscripts”的错误。

第二次的代码更是混淆了元组和数组的访问语法,$0.0是元组的访问方式,但这里$0要么是Int要么是数组,所以肯定也报错。

实现双向两两对比的正确方案

你的需求是每个元素都要和其他所有元素(包括顺序相反的配对,比如[A,B]和[B,A]都要单独对比),当满足“第一个数组的两个元素分别是第二个数组对应元素的倍数”时,计数加1。下面给你两种可行的实现方式:

方式一:嵌套循环(直观易懂)

这是最容易理解的写法,适合刚接触Swift集合操作的场景:

var arrayExample = [[4,8],[15,30],[25,50]]
var noOfSimiRect = 0

// 遍历每个元素作为对比的左项
for i in 0..<arrayExample.count {
    let left = arrayExample[i]
    // 遍历每个元素作为对比的右项,跳过和自己对比的情况
    for j in 0..<arrayExample.count {
        guard i != j else { continue }
        let right = arrayExample[j]
        // 检查倍数条件
        if left[0].isMultiple(of: right[0]) && left[1].isMultiple(of: right[1]) {
            noOfSimiRect += 1
        }
    }
}

print(noOfSimiRect) // 针对你的示例数组,这里输出0,因为没有满足条件的配对

方式二:用reduce()实现(更函数式)

如果你坚持要用reduce(),可以结合enumerated()来避免元素和自身对比,同时累加符合条件的数量:

let arrayExample = [[4,8],[15,30],[25,50]]

let noOfSimiRect = arrayExample.enumerated().reduce(0) { total, currentItem in
    let (currentIndex, current) = currentItem
    // 统计当前元素和其他所有非自身元素满足条件的数量
    let matchedCount = arrayExample.enumerated()
        .filter { $0.offset != currentIndex } // 排除自身
        .filter { _, other in
            current[0].isMultiple(of: other[0]) && current[1].isMultiple(of: other[1])
        }
        .count
    return total + matchedCount
}

print(noOfSimiRect) // 同样输出0

测试验证

如果换一个有满足条件配对的数组,比如[[2,4],[4,8],[1,2]]:

  • [2,4]和[1,2]满足条件(2是1的倍数,4是2的倍数)
  • [4,8]和[2,4]、[1,2]都满足条件
  • [1,2]和其他元素都不满足条件
  • 反向配对中,[1,2]和[2,4]、[4,8]也不满足,所以最终计数是3([2,4]→[1,2],[4,8]→[2,4],[4,8]→[1,2])

上面的两种方案都能正确统计这个结果。

内容的提问来源于stack exchange,提问作者ilakk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 04:57:36