Ios 两个字符串数组的双精度数组

Ios 两个字符串数组的双精度数组,ios,arrays,swift,Ios,Arrays,Swift,假设我有两个数组: let arrayOne = ["Hi", "Hi", "Hello", "Not Hey", "Howdy", "Hi"] let arrayTwo = ["Hi", "Hello", "Hey", "Not Howdy", "Hi", "Hi"] 我有一个for循环,它得到了双打的相似性百分比: var matches = 0 for (index, item) in enumerate(arrayOne) { if item == arrayTwo[inde

假设我有两个数组:

let arrayOne = ["Hi", "Hi", "Hello", "Not Hey", "Howdy", "Hi"]
let arrayTwo = ["Hi", "Hello", "Hey", "Not Howdy", "Hi", "Hi"]
我有一个for循环,它得到了双打的相似性百分比:

var matches = 0

for (index, item) in enumerate(arrayOne) {
    if item == arrayTwo[index] {
        matches++
    }
}

但是,如果这些数组较长,并且我想要这些相似性的数据点,而不是一次计算,该怎么办。我可以写一个什么样的函数,它从数组中取出前5个元素,返回它们与for循环的相似性,然后转到下5个?它将是一个接受两个字符串数组并返回一个双精度数组的函数。我相信这是一个简单的问题,但我不知道如何一次获取5个数组元素,然后返回一个双精度数组(如数据点和字符串数组相似性)

我不太清楚你在问什么,但是,你可能会发现玩
zip
map
reduce
很有帮助

例如,您可以像这样重写原始循环(假设Swift 2.0,您必须稍微重新安排1.2):

zip
在每个对应位置创建一个新的元素对序列

reduce
获取一个起始值,然后通过对序列中的当前值和下一个值应用函数来保持一个运行值–记住这是一个成对元素的序列,当它们相同时,您希望添加1,当它们不相同时,希望添加0。然后,这将为您提供两者匹配的位置计数

相反,如果您想要一个数组,true表示该点上的匹配,false表示不同,则可以使用
map

zip(arrayOne, arrayTwo).map(==)
// returns [true, false, false, false, false, true]
另一方面,如果您需要每个位置两个字符串之间字符串长度差异的列表,可以将其更改为:

zip(arrayOne, arrayTwo).map { (a,b) in
    a.characters.count - b.characters.count 
}
// returns [0, -3, 2, -2, 3, 0]
正如一些人所建议的,
Set
可能会有所帮助,例如:

let commonElements = Set(arrayOne).intersect(arrayTwo)
// returns strings present in both e.g. {"Hi", "Hello”}

如果您可以将数据作为一个集合来处理,即顺序无关紧要,重复项可以忽略,那么这是一个很好的方法。如果顺序和重复确实很重要,你可能必须坚持使用数组。

我不太清楚你在问什么,但是,你可能会发现玩
zip
map
reduce
很有帮助

例如,您可以像这样重写原始循环(假设Swift 2.0,您必须稍微重新安排1.2):

zip
在每个对应位置创建一个新的元素对序列

reduce
获取一个起始值,然后通过对序列中的当前值和下一个值应用函数来保持一个运行值–记住这是一个成对元素的序列,当它们相同时,您希望添加1,当它们不相同时,希望添加0。然后,这将为您提供两者匹配的位置计数

相反,如果您想要一个数组,true表示该点上的匹配,false表示不同,则可以使用
map

zip(arrayOne, arrayTwo).map(==)
// returns [true, false, false, false, false, true]
另一方面,如果您需要每个位置两个字符串之间字符串长度差异的列表,可以将其更改为:

zip(arrayOne, arrayTwo).map { (a,b) in
    a.characters.count - b.characters.count 
}
// returns [0, -3, 2, -2, 3, 0]
正如一些人所建议的,
Set
可能会有所帮助,例如:

let commonElements = Set(arrayOne).intersect(arrayTwo)
// returns strings present in both e.g. {"Hi", "Hello”}

如果您可以将数据作为一个集合来处理,即顺序无关紧要,重复项可以忽略,那么这是一个很好的方法。如果顺序和重复确实重要,您可能必须坚持使用数组。

看看这个。我认为它符合你的要求。通过引入
count
变量来跟踪已处理的项目数量,您将知道何时更新
counts
数组:

var matches = 0

let arrayOne = ["Hi", "Hi", "Hello", "Not Hey", "Howdy", "Hi", "a", "b", "c"]
let arrayTwo = ["Hi", "Hello", "Hey", "Not Howdy", "Hi", "Hi", "a", "B", "C"]

var count = 0
var counts:[Int] = []

for (index, item) in enumerate(arrayOne) {
    if item == arrayTwo[index] {
        matches++
    }
    // Have we done 5?  If so, time to update counts array
    if ++count == 5 {
        counts.append(matches)
        count = 0
        matches = 0
    }
}
// If we didn't have 5, just append the matches for the remaining items
if count > 0 {
    counts.append(matches)
}

println(counts)  // prints "[1, 2]"

看看这个。我认为它符合你的要求。通过引入
count
变量来跟踪已处理的项目数量,您将知道何时更新
counts
数组:

var matches = 0

let arrayOne = ["Hi", "Hi", "Hello", "Not Hey", "Howdy", "Hi", "a", "b", "c"]
let arrayTwo = ["Hi", "Hello", "Hey", "Not Howdy", "Hi", "Hi", "a", "B", "C"]

var count = 0
var counts:[Int] = []

for (index, item) in enumerate(arrayOne) {
    if item == arrayTwo[index] {
        matches++
    }
    // Have we done 5?  If so, time to update counts array
    if ++count == 5 {
        counts.append(matches)
        count = 0
        matches = 0
    }
}
// If we didn't have 5, just append the matches for the remaining items
if count > 0 {
    counts.append(matches)
}

println(counts)  // prints "[1, 2]"

对-所以我想我理解你在寻找什么:你想要一个
匹配
函数,就像你写的那样,它可以处理一定数量的元素块。首先,您需要一个块函数。关于它们有很好的讨论,但是它们是针对数组的,您需要在这里将两个数组压缩在一起,因此您需要一个用于
SequenceType
。这项工作:

public extension SequenceType {

  /// Returns an array of arrays of n non-overlapping elements of self
  /// - Parameter n: The size of the chunk
  ///  ```swift
  ///  [1, 2, 3, 4, 5].chunk(2)
  ///
  ///  [[1, 2], [3, 4], [5]]
  /// ```

  func chunk(_ n: Int) -> [[Generator.Element]] {
    var g = self.generate()
    var ret: [[Generator.Element]] = [[]]
    while let next = g.next() {
      if ret.last!.count < n {
        ret[ret.endIndex.predecessor()].append(next)
      } else {
        ret.append([next])
      }
    }
    return ret
  }
}

因为在前五个函数中有一个匹配项,在最后一个函数中也有一个匹配项。

对-所以我想我理解你在寻找什么:你希望有一个
匹配项
函数,就像你编写的函数一样,可以处理一定数量的元素块。首先,您需要一个块函数。关于它们有很好的讨论,但是它们是针对数组的,您需要在这里将两个数组压缩在一起,因此您需要一个用于
SequenceType
。这项工作:

public extension SequenceType {

  /// Returns an array of arrays of n non-overlapping elements of self
  /// - Parameter n: The size of the chunk
  ///  ```swift
  ///  [1, 2, 3, 4, 5].chunk(2)
  ///
  ///  [[1, 2], [3, 4], [5]]
  /// ```

  func chunk(_ n: Int) -> [[Generator.Element]] {
    var g = self.generate()
    var ret: [[Generator.Element]] = [[]]
    while let next = g.next() {
      if ret.last!.count < n {
        ret[ret.endIndex.predecessor()].append(next)
      } else {
        ret.append([next])
      }
    }
    return ret
  }
}

因为前五个匹配项中有一个匹配项,最后一个也有一个匹配项。

看看如何使用
集合
而不是数组。看看如何使用
集合
而不是数组。