list - 创建键值对列表
问题描述
我有这些事实:
name(john),
name(mary),
name(jack),
当我“迭代”所有事实时,我会为每个名称找到类似于评级(一个数字)的东西。我希望该评级与 2-john 或 john-2 之类的名称配对,将它们存储在列表中并根据数字对列表进行排序。我怎样才能在 ProLog 中做到这一点?
name(PersonsName), findRating(PersonsName, Rating), fail.
解决方案
@false 在评论中给出了正确答案:
setof(V-K, ( name(K), rating(K, V) ), VKs)
@false 的个人笑话,不止:-
. :)
我将在这里为那些需要缺失部分的人进行扩展。
首先,事实必须是事实,即
name(john),
不是事实,因为它以 a 结尾,
。事实需要以句点 ( .
) 结束。
需要下一个事实来将评级与该人相关联。
rating(john,2).
rating(mary,3).
rating(jack,4).
现在为setof/3
setof/3 的签名是setof(+Template, +Goal, -Set)
Goal
是将返回所需数据的查询,在这种情况下,目标name(K), rating(K,V)
是()
( name(K), rating(K, V) )
示例运行:
?- name(Name),rating(Name,Rating).
Name = john,
Rating = 2 ;
Name = mary,
Rating = 3 ;
Name = jack,
Rating = 4.
虽然这为我们提供了所需的数据,但它并不是一种有用的格式并一个一个地返回结果。
Template
是结果中数据的格式,在这种情况下V-K
,其中V
forValue
是评分,K
forKey
是键。结果会是这样2-john
。
这是到目前为止我们通过查询和示例运行演示的示例:
rating(V-K) :-
name(K),
rating(K,V).
?- rating(Ratings).
Ratings = 2-john ;
Ratings = 3-mary ;
Ratings = 4-jack.
请注意,结果以正确的格式返回,但仍不在列表中。
Set
是收集到结果中的内容。
由于您要求排序结果,setof/3
因此使用而不是bagof/3
. 如中所述setof/3
:sorts the result using sort/2 to get a sorted list of alternatives without duplicates.
为了更容易运行查询而不是每次都输入整个 setof/3,只需将其放入谓词中即可。
ratings(VKs) :-
setof(V-K,(name(K),rating(K,V)),VKs).
完整的代码。
name(john).
name(mary).
name(jack).
rating(john,2).
rating(mary,3).
rating(jack,4).
ratings(VKs) :-
setof(V-K,(name(K),rating(K,V)),VKs).
示例运行:
?- ratings(VKs).
VKs = [2-john, 3-mary, 4-jack].
注意:这也可以使用library(assoc): Association lists来完成,但是对于这个问题,使用setof/3
更加简洁。
推荐阅读
- virtual-machine - 创建没有 VPC 的 GCloud VM 实例
- c++ - 如何解决可能的唯一组合问题
- reactjs - 我应该使用全局状态还是 React hook 的本地状态?
- react-native - 使用 react-native 隐藏我要拨打的电话号码的电话
- python - python dicts - 将现有dict上的值从列表转换为集合
- node.js - nodejs - GraphicMagick - 在框架中添加图像以创建另一个图像
- apache - 如何将 .dat 类型添加到 apache mime.types?
- python - 蟒蛇提示中的pygame
- microsoft-graph-api - 用户日历可能存在哪些 Microsoft 图形订阅限制
- sql - 将 varchar 转换为日期 PostgreSQL