按自定义顺序排序列表
Posted
技术标签:
【中文标题】按自定义顺序排序列表【英文标题】:Sort List by custom order 【发布时间】:2021-04-02 13:42:08 【问题描述】:给出一个列表,例如
[id: 4, id: 5, id: 4, id: 7, id: 6, id: 4, id: 5, id: 7]
并给出另一个列表
[5, 7, 6, 4]
如何根据第二个列表的值对第一个列表进行排序?
(即获得
[id: 5, id: 5, id: 7, id: 7, id: 6, id: 4, id: 4, id: 4]
结果)
【问题讨论】:
【参考方案1】:你可以试试这样的:
void main()
List<Map<String, dynamic>> list = [
"id": 4,
"id": 5,
"id": 4,
"id": 7,
"id": 6,
"id": 4,
"id": 5,
"id": 7
];
List<int> orderBy = [5, 7, 6, 4];
List sorted = [];
orderBy.forEach((val) => list
.forEach((ele) => ele.values.first == val ? sorted.add(ele) : ""));
print(sorted);
【讨论】:
这很好而且很紧凑,但是没有尽可能的节省时间。这是 O(m * n),其中 m 是要排序的列表的长度,n 是要排序的列表的长度。这可能已经足够好,但这也可以在 O(m + n) 时间内完成(以更多空间为代价),如果列表非常大,这可能很重要。 我要更改已接受的答案,因为我使用的是@jamesdlin 答案,希望没问题【参考方案2】:我首先会构建一个逆映射,将 ID 值映射到具有该 ID 的所有条目的列表。从那里可以直接遍历指定所需顺序的第二个列表,从逆映射中查找条目,然后将结果拼接在一起:
void main()
var items = <Map<String, int>>[
'id': 4,
'id': 5,
'id': 4,
'id': 7,
'id': 6,
'id': 4,
'id': 5,
'id': 7,
];
var orderBy = [5, 7, 6, 4];
var idToItems = <int, List<Map<String, int>>>;
for (var item in items)
(idToItems[item['id']] ??= []).add(item);
var sorted = <Map<String, int>>[
for (var id in orderBy)
...idToItems[id],
];
print(sorted);
这种方法稍微复杂一些,但它的时间复杂度应该是 O(m + n)(其中 m 是 items
的长度,n 是 orderBy
的长度):
idToItems
) 需要 O(m) 时间。对于items
的 m 个元素中的每一个:
查找或插入idToItems
,时间复杂度为 O(1)。
将该条目附加到具有相同 ID 的条目列表中,该 ID 应该是 O(1) 摊销。
迭代orderBy
是 O(n)。
将子列表整体拼接在一起需要 O(m)。
【讨论】:
谢谢陛下。目前不在我的办公桌前,但如果有问题,我会检查并提出问题。非常感谢您抽出时间来发帖。以上是关于按自定义顺序排序列表的主要内容,如果未能解决你的问题,请参考以下文章
在 Eloquent 中按自定义顺序对集合进行排序 [重复]