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
相关产品推荐
相关产品推荐

