如何筛选Swift结构体数组中amount值最大的前X个元素
筛选数组中amount最大的前X个元素
常规实现(代码简洁,适合中小数据量)
直接对数组按amount降序排序,再取前X个元素即可。这种方法代码简单易维护,适合数据量不大的场景。
// 替换topCount为你需要的X值 let topCount = 5 // 降序排序后取前X个,转成数组用Array()包裹 let topXStats = Array(stats.array.sorted { $0.amount > $1.amount }.prefix(topCount))
性能优化实现(适合超大数据量)
如果数组填充的数据量极大(比如十万级以上),全量排序的时间复杂度为O(n log n),会造成不必要的性能损耗。这时可以用小顶堆来实现,时间复杂度优化为O(n log X),只维护最大的前X个元素,避免全量排序。
先实现一个小顶堆结构:
struct MinHeap<T: Comparable> { private var elements: [T] = [] var count: Int { elements.count } mutating func insert(_ element: T) { elements.append(element) siftUp(from: elements.count - 1) } mutating func extractMin() -> T? { guard !elements.isEmpty else { return nil } if elements.count == 1 { return elements.removeLast() } let minElement = elements[0] elements[0] = elements.removeLast() siftDown(from: 0) return minElement } private mutating func siftUp(from index: Int) { var childIndex = index let child = elements[childIndex] var parentIndex = (childIndex - 1) / 2 while childIndex > 0 && child < elements[parentIndex] { elements[childIndex] = elements[parentIndex] childIndex = parentIndex parentIndex = (childIndex - 1) / 2 } elements[childIndex] = child } private mutating func siftDown(from index: Int) { var parentIndex = index let elementCount = elements.count while true { let leftChildIndex = parentIndex * 2 + 1 let rightChildIndex = parentIndex * 2 + 2 var candidateIndex = parentIndex if leftChildIndex < elementCount && elements[leftChildIndex] < elements[candidateIndex] { candidateIndex = leftChildIndex } if rightChildIndex < elementCount && elements[rightChildIndex] < elements[candidateIndex] { candidateIndex = rightChildIndex } if candidateIndex == parentIndex { break } elements.swapAt(parentIndex, candidateIndex) parentIndex = candidateIndex } } }
然后用堆筛选目标元素:
func fetchTopXStats(_ x: Int) -> [stats] { guard x > 0, !stats.array.isEmpty else { return [] } let targetCount = min(x, stats.array.count) var minHeap = MinHeap<stats>() for stat in stats.array { if minHeap.count < targetCount { minHeap.insert(stat) } else if stat.amount > minHeap.elements[0].amount { minHeap.extractMin() minHeap.insert(stat) } } // 堆内元素按小顶堆排列,最后降序排序返回 return minHeap.elements.sorted { $0.amount > $1.amount } } // 调用示例:获取前5个amount最大的元素 let top5Stats = fetchTopXStats(5)
注意事项
- 两种方法都会保留
amount相同的并列元素,只要它们处于前X的范围内。 - 如果X大于数组总长度,会返回整个数组(降序排序后的结果)。
内容的提问来源于stack exchange,提问作者user15748784
相关产品推荐
相关产品推荐

