【JS】数组对象自定义排序
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了【JS】数组对象自定义排序相关的知识,希望对你有一定的参考价值。
参考技术A replace 的语法ECMAScript v3 规定, replace() 方法的参数 replacement 可以是函数而不是字符串。在这种情况下,每个匹配都调用该函数,它返回的字符串将作为替换文本使用。该函数的第一个参数是匹配模式的字符串。接下来的参数是与模式中的子表达式匹配的字符串,可以有 0 个或多个这样的参数。接下来的参数是一个整数,声明了匹配在 stringObject 中出现的位置。最后一个参数是 stringObject 本身。
数组的自定义排序,一种是 replace ,一种是较常见易懂的 indexOf 。
数组对象排序
Swift如何使用属性按给定顺序对自定义对象数组进行排序
【中文标题】Swift如何使用属性按给定顺序对自定义对象数组进行排序【英文标题】:Swift how to sort an array of custom objects in a given order with property 【发布时间】:2017-07-30 17:51:47 【问题描述】:我有一组按特定顺序排列的餐馆 ID。我进行网络调用以获取这些 id 中的每一个的餐厅。我按所有餐厅返回的顺序返回。餐厅是一个自定义类,其中一个属性是 restaurantId。我想按 ID 的顺序对返回的餐厅进行排序。我该怎么做?我想我应该使用排序功能。我将如何继续这样做?可能有重复的餐馆,所以我不能用字典来做。如果 is 是返回的重复餐厅,那么该餐厅的哪个实例首先出现并不重要。
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......
【问题讨论】:
那将按数字排序,我想按 restaurantIds 数组中的自定义顺序对其进行排序。 您正在拨打“网络电话”,但如何?您是一个一个地请求它们,您是一次请求它们并返回一个列表,它们是否以 id 作为数据的一部分返回?我们真的需要更多信息,或者我们只是在猜测解决方案。 【参考方案1】:如果我理解正确,您希望按照 ID 在 restaurantIds
中出现的顺序对数组进行排序。
Array
提供了index(of:)
方法,它给定一个元素返回它在数组中第一次出现的索引。例如restaurantIds.index(of:858914)
将返回1
。
您可以使用index(of:)
的结果作为排序键。 IE。在您的排序函数中,您需要比较 rest1
的值将是 restaurantIds.index(of: rest1.productID)
。
HTH
附录
@vacawama raises 和 issue with 原则上都是正确的,但在实践中可能是错误的...使用restaurantIds.index(of: rest1.productID)
a lot 对性能和较长的餐厅 ID 列表不利,您可能需要通过避免重复的index(of:)
调用来优化。然而,对于简短列表,任何性能变化(可能是输赢)都可能微不足道,优化只会使代码复杂化。
TL;DR:YMMV,KISS,提防过早的优化,你的电话。
【讨论】:
我认为这就是 OP 正在寻找的。其余的答案将不起作用。 对于任何正在阅读本文的人来说,@adev 当时是正确的。现在 vacawama 的解决方案也有效,并且是对同一想法的不同看法。任君挑选。 假设 id 是唯一的,可能放入有序集合可能有助于解决索引问题。【参考方案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:)
的次数就越多(因为sort
是O(n log n)
),因此对index(of:)
的调用次数会随着餐厅数组大小的增加而迅速增长。 index(of:)
是基于 id 数组大小的 O(n)
操作。 id 数组越大,index(of:)
变得越慢。
【讨论】:
“这样更有效率……”?在示例中,restaurantIDs
很短,当然可以更长,但鉴于它的 ID 列表是要在数据库中查找的 iOS 应用程序,我们可能会猜到它并没有那么大。 dict 需要在插入和查找时进行动态分配和哈希计算。数组的index(of:)
可能需要偏移计算(可能只是迭代)并且将平均 n/2 比较。这两种方法可能更快,取决于数据,但它真的很重要吗?你确定这不是过早的优化吗? (我承认,我考虑过一个口述,我们都想不接吻 ;-))
@CRD,两种方式都有优点。如果 OP 真的只有 3 个 id,那么字典就大材小用了。餐厅 ID 列表是提前知道的,因此可以在那时创建字典,而不是等待餐厅被读取。在排序中,相同的查找会重复发生,所以n/2
加起来。我不认为这是过早的优化。它正在考虑一种可以很好地扩展的算法。使用 6 位数的餐厅 ID,可能有 3 个以上。
编辑很好,但你应该仍然有一个“可能”在那里;-)
我知道这最终会比index(of:)
更有效率。我心中唯一剩下的问题是盈亏平衡点在哪里。如果可以提前创建字典,那么盈亏平衡点就更低了。
我们在这里跳舞,我说“可能”,你说“最终”;-) 你明白了我的原意,但表达得不好,很高兴与你交谈。【参考方案3】:
一种方法是使用flatMap
遍历restaurantIds
数组,并返回returnedRestaurant
数组中id 与restaurantIds
中当前索引处的id 匹配的第一个元素。此函数返回一个新的排序数组,并且不会改变 returnedRestaurant
数组。
let sortedRestaurants = restaurantIds.flatMap id in
returnedRestaurant.filter$0.restaurantId == id .first
【讨论】:
如果你在 restaurantIds 上使用 flatmap 函数,它会展平 restaurantIds 数组,但我们不想展平数组,我们只想根据 restaurantIds 数组使用的顺序对返回的餐厅进行排序每个餐厅内的 id。我还没有尝试过,但是如果您认为它会起作用,我会尝试一下。 只要你没有重复的 restaurantIds 就可以了。如果您确实有重复 ID,那么这会删除除找到的第一家餐厅之外的所有餐厅。 @vacawama 你是对的,我认为 id 是唯一的。但是这个解决方案可以很容易地修改为也可以使用重复的 id。以上是关于【JS】数组对象自定义排序的主要内容,如果未能解决你的问题,请参考以下文章