我有一个对象数组,结构如下:
{
id: String,
userId: String,
distance: Double,
time: Double
}
字符串
在数组中,同一个userId
在同一个距离上可以有多个条目。例如,数组可以是:
[
{ id: "1", userId: "1", distance: 100, time: 18.7 },
{ id: "2", userId: "1", distance: 100, time: 18.5 },
{ id: "3", userId: "2", distance: 100, time: 18.2 },
{ id: "4", userId: "2", distance: 200, time: 41.0 },
]
型
我想过滤和排序数组,使数组只包含每个用户在一定距离内的最快时间。所以如果我想使用上面的数组查找100次,它只会返回:
[
{ id: "3", userId: "2", distance: 100, time: 18.2 },
{ id: "2", userId: "1", distance: 100, time: 18.5 },
]
型
我知道我可以使用.filter
将它减少到100次,使用.sort
将时间按顺序排列,但我不知道如何将每个userId
限制为1个条目。
4条答案
按热度按时间6tdlim6h1#
您可以使用我添加到
swift-algorithms
(Apple托管的第一方包,就像Swift标准库的附件)的新grouped(by:)
函数。我们可以根据比赛的距离和参加比赛的用户对所有的比赛结果进行分组。在每组结果中,我们将选择一个最快的时间(该用户在该距离内)。我称之为
userPersonalRecords
。从那里,我们可以通过距离过滤,得到每个人最好的100米短跑。
如果我们经常这样做,可能值得按距离对比赛结果进行分组,并保留结果数组。或者,如果你有 * 很多 * 结果,你可以将所有这些转储到一个小SQLite DB中,并根据需要使用查询进行相同的简单分组/排序。
字符串
mrwjdhj32#
虽然像
sort
、filter
和map
这样的操作可能很有用,并且可以简化代码,但它们都将遍历数组。使用数组"操作",你需要:
filter
阵列仅包括所需的距离sort
数组的用户ID和时间compactMap
只返回每个用户的第一次(由于排序,您知道每个用户的第一次是最快的)这涉及到迭代数组(或它的子集)两次,并排序两次。
字符串
另一种方法是使用
for
循环来将数组转换为:循环完成后,你仍然需要对减少的数组按
time
排序,以找到最快的时间:型
它不仅减少了代码,而且您现在只需遍历整个数组一次,并对减少的数组进行排序一次。
你可以使用
reduce
代替for
循环,但我认为这会导致代码不太清晰,而且没有性能优势。uemypmqf3#
有很多方法可以解决这个问题。
我可能会将数据重构为以userID为键的结构体字典。
如果距离只是一个小的集合,(例如50 M,100 M,500 M,1000 M,10,000 M)我可能会为每个距离创建带有种族数组的结构体:
字符串
然后,如果你想让用户拥有最快的gift meter时间,你只需遍历所有的键/值对,比较
fiftyRaces
中该用户的第一个条目,寻找时间最短的那个。drnojrws4#
下面是我的解决方案,使用
reduce(into:)
,只迭代数组一次字符串