sorting - 根据 2 个键对序言中的列表进行排序
问题描述
假设我有这个列表。
A=[(a,1), (b,3), (d,2), (c,2)]
我想根据两件事对其进行排序,首先我检查数字,如果它们相同,我需要按字母进行排序,例如这将被排序为:
S=[(a,1), (c,2), (d,2), (b,3)]
如果我用这个
sort(2, @=<, A, S).
我得到的是排序的列表,但仅基于数字,如何添加该加控件?
解决方案
根据sort/4
'@=<' 表示“升序排序,但不消除重复”。
如果我们接受重复消除,我们可以使元谓词适应predsort/3
我们的需要。
predsort(+Pred, +List, -Sorted)
这只是其他编程语言中已知的“排序方法”的另一种形式。例如,在 Java 中有Collections.sort
一个Comparator
接口。在这里,predsort/3
将谓词名称Pred
(或部分填充的谓词调用)作为可调用过程。一样。
谓词compare/3
正是我们需要进行元素比较的,因为它使用标准的术语顺序来比较整个术语:
?- compare(D,(a,1),(b,3)).
D = (<).
?- compare(D,(a,1),(a,3)).
D = (<).
?- compare(D,(a,3),(a,1)).
D = (>).
?- compare(D,(b,3),(a,1)).
D = (>).
但是,它首先按第一个子元素进行比较,其次按第二个子元素进行比较(或更准确地说,按具有函子名称的复合项的参数顺序,
)
所以我们必须先扭转这些。这是通过另一个元maplist/3
谓词完成的,其中“将一个列表的元素映射到另一个列表的元素的谓词”将是“反转的谓词”。由于我懒得为此添加单独的谓词,我将使用library(yall)
:[(C,N),(N,C)]>>true
等效于reverse((C,N),(N,C))
.
所以:
my_sort(ListIn,ListOut) :-
maplist([(C,N),(N,C)]>>true,ListIn,List2),
predsort(compare,List2,List3),
maplist([(C,N),(N,C)]>>true,ListOut,List3).
所以:
?- my_sort([(a,1), (b,3), (d,2), (c,2)], Out).
Out = [(a, 1), (c, 2), (d, 2), (b, 3)].
请注意,(A,B)
成对使用结构不是完美的风格 -,
是连词。改用实际的对:(A-B
即真正-(A,B)
的结构)。
它适用于空列表吗?是的,它确实。
?- my_sort([],[]).
true.
更完整的例子在这里:
推荐阅读
- python - 检查压缩数据似乎会删除它
- sql - 获取 ORA-00907:当左侧没有额外括号时缺少右括号
- php - 如何在 laravel 中为每个用户生成唯一的自动增量值并将其添加到数据库中
- java - 运行时的 Logback java 配置
- java - 如何在 java swing 中使用套接字显示通知
- spring-boot - 每个 Spring Boot 实例 2 个 Hazelcast 成员
- svn - 删除所有权限(Visual SVN 2.1.2)
- ios - 如何在 tvOS 的 UICollectionView 中隐藏滚动指示器等内容
- angular - ReferenceError:未定义语音识别
- reactjs - 使用reactjs发生拖动时如何读取材料表列标题数组