You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何筛选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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 03:40:35