Swift如何使用属性按给定顺序对自定义对象数组进行排序

时间:2017-07-30 17:51:48

标签: ios arrays swift sorting swift3

我有一系列的餐馆ID按特定顺序排列。我打网络电话为这些ID中的每一个获取餐馆。我按照退货的顺序退回所有餐馆。餐厅是一个定制类,其中一个属性是restaurantId。我想按照ID的顺序对返回的餐馆进行排序。我该怎么办?我想我应该使用排序函数。我将如何继续这样做?可能有重复的餐馆,所以我不能用字典来做。如果是返回的复制餐厅,那么该餐厅的哪个实例首先出现并不重要。

var restaurantIds = [947575, 858914, 255964]
var returnedRestaurant:[Restaurant]!
returnedRestaurant.sorted { (rest1, rest2) -> Bool in
        //How would I go about matching rest1 and rest2 to the list of restaurantIds above?
        rest1.productID......
    }

3 个答案:

答案 0 :(得分:3)

如果我理解正确,您希望按照// a is a shared_ptr for(int i=0;i<N;i++) { a[i]+=1; } 中ID的顺序对数组进行排序。

restaurantIds提供方法Array,给定一个元素返回它在数组中第一次出现的索引。例如,index(of:)会返回restaurantIds.index(of:858914)

您可以使用1的结果作为排序键。即在排序功能中,您需要比较index(of:)的值为rest1

HTH

<强>附录

@vacawama提出并且问题在原则上是正确的但在实践中可能是错误的...使用restaurantIds.index(of: rest1.productID) 批次不利于性能和更长的餐馆ID列表您可能需要通过避免重复的restaurantIds.index(of: rest1.productID)调用进行优化。然而,对于简短列表,任何性能变化(可能是输赢)都可能是微不足道的,优化只会使代码复杂化。

TL; DR:YMMV,KISS,注意过早优化,你的电话。

答案 1 :(得分:2)

创建一个字典,将restaurantID映射到该ID的顺序。然后,您可以使用它来对数组进行排序:

var restaurantIds = [947575, 858914, 255964]

// Create a dictionary that maps the order of the restaurantID
var order = [Int: Int]()
for (idx, rid) in restaurantIds.enumerated() {
    order[rid] = idx
}

var returnedRestaurant:[Restaurant]!

returnedRestaurant.sort { (rest1, rest2) -> Bool in

    // look up the order for the restaurant id.  If the id is missing, use
    // Int.max to put that restaurant at the end of the array

    let order1 = order[rest1.id] ?? Int.max
    let order2 = order[rest2.id] ?? Int.max

    return order1 < order2
}

如果你有不止一些餐馆ID,这可能比重复使用index(of:)来计算映射更有效。您的餐馆阵列越大,index(of:)被调用的次数就越多(因为sortO(n log n))所以index(of:)的来电次数会随着餐厅数组的大小而迅速增长增加。 index(of:)是基于id数组大小的O(n)操作。 id数组越大,index(of:)变慢。

答案 2 :(得分:0)

执行此操作的一种方法是使用restaurantIds遍历flatMap数组,并返回returnedRestaurant数组中的第一个元素,其id与{{{}中当前索引的id匹配1}}。此函数返回一个新的已排序数组,并且不会改变restaurantIds数组。

returnedRestaurant