创建较小的均匀分布的数组

时间:2019-03-13 14:25:41

标签: arrays swift algorithm

我正在尝试从较大的数组创建较小的数组。

我需要将数组中的项目均匀分布以匹配较大的数组。

因此,例如,较大的数组包含420个项目。较小的数组包含375。

我可以使用以下代码在合理的误差范围内获得所需的结果:

var smallArray = []
let smallArraySize = 375
//largeArray contains 420 items
let difference = largeArray.count - smallArraySize
let step = ceil(largeArray.count / smallArraySize)

for (index, item) in largeArray.enumerated {
  if index % Int(step) != 0 {
     smallArray.append(item)
  }
}

这将导致包含373个项目的 smallArray 。达到我的要求。

但是,如果大型数组包含更多项目(例如1020),则此方法不再起作用。

特别是,当差异大于 smallArraySize 时,这似乎是一个问题。

在更大数量上使用相同代码将导致 step (步骤1)为1,因此新数组为空。

1 个答案:

答案 0 :(得分:1)

如果将每个索引从较小的数组映射到较大的数组的合适索引,则可以使用“几乎均匀分布”的元素创建子数组:

extension Array {
    func subArray(withSize n: Int) -> [Element] {
        precondition(n >= 0 && n <= count)
        return (0..<n).map { self[($0 * count + count/2)/n] }
    }
}

示例:

let array = [0, 1, 2, 3, 4, 5, 6, 7]

print(array.subArray(withSize: 1)) // [4]
print(array.subArray(withSize: 2)) // [2, 6]
print(array.subArray(withSize: 3)) // [1, 4, 6]
print(array.subArray(withSize: 4)) // [1, 3, 5, 7]
print(array.subArray(withSize: 5)) // [0, 2, 4, 5, 7]
print(array.subArray(withSize: 6)) // [0, 2, 3, 4, 6, 7]
print(array.subArray(withSize: 7)) // [0, 1, 2, 4, 5, 6, 7]
print(array.subArray(withSize: 8)) // [0, 1, 2, 3, 4, 5, 6, 7]

下图大致显示了如何从八个元素中选出三个:

┌──┬──┬──┬──┬──┬──┬──┬──┐
│ 0│ 1│ 2│ 3│ 4│ 5│ 6│ 7│
└──┴──┴──┴──┴──┴──┴──┴──┘
    ⬆      ⬆      ⬆︎   
┌───────┬───────┬───────┐
│   0   │   1   │   2   │
└───────┴───────┴───────┘