arrays - 哪种方法更好,每次保存一个值或评估?

标签 arrays swift optimization higher-order-functions

我正在尝试了解以下哪项是更好的方法。

我有一个 Arraystruct

struct A {
    var selectionCount: Int
}

var ayes = [A]()

如果我想知道是否选择了任何元素,我是否应该每次循环这些项目。

func selectedCount() -> Int {
    return ayes.filter({ $0.selectionCount != 0 }).reduce(0, +)
}
// OR

存储一个 var 并在每次我想知道是否已做出任何选择时访问它。

var totalSelectedElements = 0

func select(at: Int) {
    ayes[at].selectionCount += 1
    totalSelectedElements += 1
}

func deselect(at: Int) {
    ayes[at].selectionCount -= 1
    totalSelectedElements -= 1
}

最佳答案

区分接口(interface)实现很重要。首先设计您想要的接口(interface),然后您可以随时更改内部实现以满足您的(性能与存储)需求。

我相信 A 的数组应该受到保护,您应该只允许通过 select(at:) 访问和 deselect(at:)方法。这允许您以任何一种方式进行内部实现:

struct Ayes {
    private struct A {
        var selectionCount = 0
    }

    private var ayes = [A](repeating: A(), count: 100)
    private var totalSelectedElements = 0

    mutating func select(at: Int) {
        ayes[at].selectionCount += 1
        totalSelectedElements += 1
    }

    mutating func deselect(at: Int) {
        guard ayes[at].selectionCount > 0 else { return }
        ayes[at].selectionCount -= 1
        totalSelectedElements -= 1
    }

    func selectCount(at: Int) -> Int {
        return ayes[at].selectionCount
    }

    var totalElements: Int {
        return totalSelectedElements
    }
}

这实际上取决于您访问 totalElements 的频率是否要存储它或计算它。通过隐藏该实现细节,您可以自由更改实现而不会影响程序的其余部分。

我喜欢维护计数以便快速访问的想法,并且通过保护对内部实现的访问,您可以保证计数是准确的。


示例:

var ayes = Ayes()

print(ayes.totalElements) // 0
ayes.select(at: 3)
ayes.select(at: 3)
ayes.select(at: 4)
print(ayes.totalElements) // 3
print(ayes.selectCount(at: 3)) // 2
ayes.deselect(at: 3)
print(ayes.selectCount(at: 3)) // 1
ayes.deselect(at: 3)
print(ayes.selectCount(at: 3)) // 0
ayes.deselect(at: 3)
print(ayes.selectCount(at: 3)) // 0
print(ayes.totalElements) // 1

替代实现 - 相同的界面

此解决方案结合了 @RakeshaShastri's suggestion将字典与您维护计数的想法结合使用:

struct Ayes {
    private var ayes = [Int : Int]()
    private var totalSelectedElements = 0

    mutating func select(at: Int) {
        ayes[at, default: 0] += 1
        totalSelectedElements += 1
    }

    mutating func deselect(at: Int) {
        guard var count = ayes[at] else { return }
        count -= 1
        totalSelectedElements -= 1
        ayes[at] = count == 0 ? nil : count
    }

    func selectCount(at: Int) -> Int {
        return ayes[at, default: 0]
    }

    var totalElements: Int {
        return totalSelectedElements
    }
}

这避免了对预分配数组的需要,但仍提供通过字典和内部计数的快速访问。

关于arrays - 哪种方法更好,每次保存一个值或评估?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52202282/

相关文章:

swift - 计算 tableview 中 name 等于的所有行

javascript - 是否可以检测 WebKit 中的尾调用优化?

arrays - 在 Swift 中将坐标字符串转换为 CLLocations 数组

java - 比较两个 int 数组并打印缺失的数字

java - 如何遍历 Object 引用的数组?

javascript - 我无法使用 .filter() 方法来过滤正确的索引

arrays - Swift 无法访问单个对象数组

ios - 我如何对 Musik 的开关和按钮进行编程?

image - Google PageSpeed Insights 优化运行新图像压缩的图像?

mysql - 加快 26 秒 mysql 查询速度