【发布时间】:2016-10-13 04:25:28
【问题描述】:
可以在 swift 中像这样过滤数组:
var numbers = Array(1...1000000)
numbers = numbers.filter( { return $0 % 2 == 0 } )
是否可以过滤并避免在过滤完成时发生的复制操作,例如改变原始数组。
与此伪代码类似: numbers.MutablefilterOperation({ return $0 % 2 == 0})
在 C++ 中,与上面 Swift 中发生的事情等价的是:
std::vector<int> originalNumbers(1000000);
std::vector<int> newNumbers;
std::copy_if (originalNumbers.begin(), originalNumbers.end(), std::back_inserter(newNumbers), [](int i) { return i % 2 == 0 } );
出于性能原因我希望达到的目标:
std::vector<int> originalNumbers(1000000);
auto pos = std::remove_if(originalNumbers.begin(), originalNumbers.end(), [](int x) { return x % 2 == 0; });
originalNumbers.erase(pos, originalNumbers.end());
【问题讨论】:
-
你必须澄清。我们是在谈论任意数组还是您生成的数组?如果它是任意的,那么任何方法都将涉及查看每个索引。如果它已生成,那么您可以使用自定义生成方法来生成“过滤”元素。
-
你发现你当前的代码有什么不干净的地方?如果您真的对此有强烈的感觉,您可以随时编写自己的
filterInPlace方法作为Array的扩展。另外顺便说一句,你可以把你的过滤器写成numbers = numbers.filter{$0 % 2 == 0} -
Array是一个struct具有值语义,它不能被变异。它的任何突变都只是替换原来的。 -
What do you find un-clean about your current code?它的操作成本为 2 * O(n) ... 副本 O(n) 被命中一次,过滤器 O(n) 被命中一次。是的,这减少到“O(n)”,因为 Big O 表示法会丢弃标量,但老实说,2 的因子 很重要。如果 Swift 提供了一个开箱即用的filterInPlace方法,那么就有可能实现实际的 O(n) 运行时。 -
我也想知道同样的事情。 Apple 的 API 设计指南告诉我们以 'ed' 或 'ing' 结尾来命名非变异方法——所以我们将
sorted()作为sort()的非变异对应物。那么为什么他们在命名filter()时忽略了自己的准则呢?不应该叫filtered()吗?
标签: arrays swift filtering immutability