Ios 计数包含相同两个值的数组数
给定一个Ios 计数包含相同两个值的数组数,ios,arrays,dictionary,swift,Ios,Arrays,Dictionary,Swift,给定一个字典查找数组中第一个5项中有多少项具有相同的两个指定值 例如: 鉴于: let numberSeries = [ "20022016": [07,14,36,47,50,02,05], "13022016": [16,07,32,36,41,07,09], "27022016": [14,18,19,31,36,04,05], ] 值:7和36,结果应该是2,因为第一个和第二个条目在条目数组的前5个条目中都有值7和36 我尝试了很多方法来实现这一点,但都没能
字典
查找数组
中第一个5
项中有多少项具有相同的两个指定值
例如:
鉴于:
let numberSeries = [
"20022016": [07,14,36,47,50,02,05],
"13022016": [16,07,32,36,41,07,09],
"27022016": [14,18,19,31,36,04,05],
]
值:7
和36
,结果应该是2
,因为第一个和第二个条目在条目数组的前5个条目中都有值7
和36
我尝试了很多方法来实现这一点,但都没能成功
这是我目前的尝试:
//created a dictionary with (key, values)
let numberSeries = [
"20022016": [07,14,36,47,50,02,05],
"13022016": [16,07,32,36,41,07,09],
"27022016": [14,18,19,31,36,04,05],
]
var a = 07 //number to look for
var b = 36 // number to look for
// SearchForPairAB // search for pair // Doesn't Work.
var ab = [a,b] // pair to look for
var abPairApearedCount = 0
for (kind, numbers) in numberSeries {
for number in numbers[0...4] {
if number == ab { //err: Cannot invoke '==' with argument listof type Int, @Value [Int]
abPairApearedCount++
}
}
}
这就产生了错误:
无法使用Int类型的参数列表@Value[Int]
调用“==”:如果number==ab您不能使用=
来比较Int
和数组
,从比较的角度来看,这没有任何意义。但是,有很多不同的方法可以实现你想要做的事情。在这种情况下,我可能会使用map
/reduce
来计算您的配对
其思想是将数组中的值映射到ab
数组中的Bool
值,该值由数值是否在数组中决定。然后,将映射的Bool
s减少为单个值:true
,如果它们都是true
,或者false
。如果reduce
d值为true
,则我们找到了该对,因此我们增加了计数
var ab = [a,b] // pair to look for
var abPairApearedCount = 0
for (kind, numbers) in numberSeries {
let found = ab.map({ number in
// find is a built-in function that returns the index of the value
// in the array, or nil if it's not found
return find(numbers[0...4], number) != nil
}).reduce(true) { (result, value: Bool) in
return result && value
}
if found {
abPairApearedCount++
}
}
通过使用Swift的一些更简洁的语法,实际上可以对其进行压缩:
var ab = [a,b] // pair to look for
var abPairApearedCount = 0
for (kind, numbers) in numberSeries {
let found = ab.map({ find(numbers[0...4], $0) != nil }).reduce(true) { $0 && $1 }
if found {
abPairApearedCount++
}
}
而且,为了好玩,可以使用reduce
而不是for in
循环进一步压缩:
var ab = [a,b] // pair to look for
var abPairApearedCount = reduce(numberSeries, 0) { result, series in
result + (ab.map({ find(series.1[0...4], $0) != nil }).reduce(true) { $0 && $1 } ? 1 : 0)
}
不过,这已经变得相当不可读了,所以我可能会将其中的一些内容进行扩展。因此,我的FP解决方案旨在将问题分解为易于消化和可重复使用的小块:
首先,我们定义一个将数组修剪为给定长度的函子:
func trimLength<T>(length: Int) -> ([T]) -> [T] {
return { return Array($0[0...length]) }
}
这是这里最难看的代码,但本质上它只是迭代检查并确保每个元素都在目标数组中。一旦我们得到了这个,我们就可以使用过滤器(array,containsAll([7,26]))
来消除数组中不包含所有目标值的所有元素
在这一点上,我们可以将整个东西粘合在一起,如下所示:
filter(map(numberSeries.values, trimLength(5)), containsAll([7, 36])).count
但是嵌套函数的长行很难阅读,让我们定义两个辅助函数和一个自定义运算符:
func rmap<S:SequenceType, T>(transform:(S.Generator.Element)->T) -> (S) -> [T] {
return { return map($0, transform) }
}
func rfilter<S:SequenceType>(predicate:(S.Generator.Element)->Bool) -> (S) -> [S.Generator.Element] {
return { sequence in return filter(sequence, predicate) }
}
infix operator <^> { associativity left }
func <^> <S, T>(left:S, right:(S)->T) -> T {
return right(left)
}
func-rmap(转换:(S.Generator.Element)->T)->(S)->[T]{
return{returnmap($0,transform)}
}
func rfilter(谓词:(S.Generator.Element)->Bool)->(S)->[S.Generator.Element]{
返回{返回筛选器中的序列(序列,谓词)}
}
中缀运算符{左结合性}
func(左:S,右:(S)->T)->T{
返回右(左)
}
和一个方便的函数来计算它的输入:
func count<T>(array:[T]) -> Int {
return array.count
}
func计数(数组:[T])->Int{
返回数组.count
}
现在我们可以把整个事情浓缩为:
numberSeries.values <^> rmap(trimLength(5)) <^> rfilter(containsAll([7, 36])) <^> count
numberSeries.values rmap(trimLength(5))RFFilter(containsAll([7,36])计数
配对指的是同一数组中的值“a”和值“b”,即前5个位置的行(这就是我使用[0…4]的原因)。我将代码分为三部分,前两部分查找数组中的单个数字,后一部分查找同一数组中的两个数字,我不知道如何编写。我尝试了不同的方法,但没有成功。我需要它输出答案“2”,因为数字“a”和“b”出现在两个不同的行中。希望这能给我们带来一些启示……正如@MikeS所说,我们不清楚您想要实现什么,但错误很简单-ab
是一个整数数组,number
是一个整数。它们是不可比的。我想我在您发送您的评论时发送了我过去的评论。希望很清楚,我不想比较这两个值。我想知道它们在同一数组中出现了多少次。该示例显示了三个数组,但我有数千个数组。我编辑了您的问题,试图根据您在此处的评论对其进行澄清。如果我遗漏了某些内容或是不知何故弄错了,请告诉我,我将回滚编辑。如果您想对高尔夫进行进一步编码,可以去掉贴图
,并将其与内部reduce
合并。
numberSeries.values <^> rmap(trimLength(5)) <^> rfilter(containsAll([7, 36])) <^> count