查找和替换数组中多个项目的最快方法

时间:2017-12-27 22:27:17

标签: arrays swift swift4

我有两个数组,大约1000个价格和大小,从最小到最大,称为tempArrayBuytempArraySell

let tempArrayBuy = [Orders]()
let tempArraySell = [Orders]()

struct Orders:Codable {
    let price : Double
    let size : Double

    init(from decoder: Decoder) throws {
        var container = try decoder.unkeyedContainer()
        price = Double(try container.decode(String.self)) ?? 0.0
        size = Double(try container.decode(String.self)) ?? 0.0
    }

    init(_ orderEntryChange: OrderChangesFeed) {
        price = orderEntryChange.price ?? 0.0
        size = orderEntryChange.size ?? 0.0
    }

}

我正在通过websocket feed对上面的两个数组进行更改。我需要在tempArrayBuy中找到正确的价格,并将该数量替换为OrderBookChangesFeed项目中的数量。

以下是来自websocket的数据格式。我有一系列的变化。

let changesNeeded = [OrderChangesFeed]()

这是数据的结构。

struct OrderChangesFeed : Codable {
    let side:String        
    let price : Double
    let size : Double

    init(from decoder: Decoder) throws {
        var container = try decoder.unkeyedContainer()
        side = try container.decode(String.self)
        price = Double(try container.decode(String.self)) ?? 0.0
        size = Double(try container.decode(String.self)) ?? 0.0
    }
}

如果边是buy,则需要更新buyTempArray,如果是sell,则需要更新sellTempArray。如果更改websocket(OrderBookChangesFeed)的价格在数组中不存在,则需要添加给定的数量/大小,如果更改websocket中与特定价格关联的数量/大小为0则它需要从tempArray中删除。

这是我现在正在做的事情。但我觉得有一种更快的方法可以做到这一点。我在一秒内得到大约10-20 +的变化,所以速度是最重要的。

for item in changesNeeded {
    if item.side == "buy"{
        if let tempInex = self.tempArrayBuy.index(where: {$0.price==item.price}) {
            if item.size == 0 {
                self.tempArrayBuy.remove(at: tempInex)
            }else {
                self.tempArrayBuy[tempInex] = Orders(item)
            }             
        }else {
            //Insert at the right spot in array. The array is sorted numerically by price. I am not sure what a fast way to do this would be.
        }
    }else {
        //Do the same thing for sell side
    }
}

我也不确定如何在数字上插入正确的位置。对此的任何帮助都会很棒!

1 个答案:

答案 0 :(得分:0)

你的两个Orders数组不应该是数组,它们应该是字典,其中price是键,大小是值。

var tempBuy: [Double: Double] = [:]
var tempSell: [Double: Double] = [:]

要最初使用您的订单数组填写上面的词典,您可以:

tempBuy = Dictionary<Double, Double>(uniqueKeysWithValues: buyOrders.map { ($0.price, $0.size) }) // the same for the sell orders.

然后你可以简单地说:

for item in changesNeeded {
    switch item.side {
    case "buy":
        tempBuy[item.price] = item.size
    case "sell":
        tempSell[item.price] = item.size
    default:
        fatalError()
    }
}

QED。

如果你真的需要这些东西的数组,那么:

var tempArrayBuy: [Orders] {
    return tempBuy
        .map { Orders(price: $0.0, size: $0.1) }
        .sorted(by: { $0.price < $1.price })
}

- 编辑 -

如果确实希望将它们保存为已排序的数组,请将整个内容包装在函数中。

func updateArrays(changesNeeded: [OrderChangesFeed], buy: inout [Orders], sell: inout [Orders]) {
    var tempBuy = [Double: Double](uniqueKeysWithValues: buy.map { ($0.price, $0.size) })
    var tempSell = [Double: Double](uniqueKeysWithValues: sell.map { ($0.price, $0.size) })
    for item in changesNeeded {
        switch item.side {
        case "buy":
            tempBuy[item.price] = item.size
        case "sell":
            tempSell[item.price] = item.size
        default:
            fatalError()
        }
    }
    buy = tempBuy
        .map { Orders(price: $0.0, size: $0.1) }
        .sorted(by: { $0.price < $1.price })
    sell = tempSell
        .map { Orders(price: $0.0, size: $0.1) }
        .sorted(by: { $0.price < $1.price })
}