给出一个整数列表的列表,例如[[3,10],[3,10,2],[5],[5,2],[5,3],[5,3,2],[5,3,10]]
,我想遍历每个子列表,并计算其中的总数为15。在这种情况下,对于子列表[3,10,2]
,该值为1。
我知道谓词aggregate_all/3
,但是我在编写谓词以检查列表的每个元素时遇到了麻烦,我现在所拥有的类似于
fifteens([X|Xs]) :-
sum_list(X, 15),
fifteens(Xs).
在另一个谓词中,我有:
aggregate_all(count, fifteens(Combinations), Value).
其中Combinations
是所讨论的整数列表的列表。
我知道我的fifteens
谓词是有缺陷的,因为它说嵌套列表的 all 个元素必须总和为15,但是要解决这个问题,我如何取出{{ 1}}并逐一检查?我什至需要吗?谢谢。
答案 0 :(得分:2)
首先,您的fifteens/2
谓词没有,因为空列表,因此它将始终失败,因为由于递归,最终fifteens([])
将被调用并失败。
此外,您还需要完全更改15个的定义,即使添加基本大小写,目前也要检查 ALL 元素-子列表以查看它们的总和是否为15。看如何将其与聚合一起使用。
要使用aggregate/3
,您需要用fifteens/2
表示,例如:对于我的组合列表的每个部分,分别检查每个子列表,即每个成员:
ifteens(L) :-
member(X,L),
sum_list(X, 15).
现在尝试:
?- aggregate_all(count, ifteens([[3,10],[3,10,2],[5],[5,2],[5,3],[5,3,2],[5,3,10]]), Value).
Value = 1.
答案 1 :(得分:1)
这是... foldl/4
的工作。逻辑编程语言中的函数式编程习惯用法?是的,我们可以!
首先,对列表的可加值求和:
public List<RemoteUsersDTO> getAllRemoteUsers() {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
String OKTA_URL = "https:bmg.okta-emea.com/api/v1/users?limit=200";
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("Authorization", "SSWS " + OKTA_API_KEY);
HttpEntity<String> request = new HttpEntity<>(headers);
String url = OKTA_URL;
List<RemoteUsersDTO> remoteUserList = new ArrayList<>();
while (url != null) {
ResponseEntity<RemoteUsersDTO[]> response = restTemplate.exchange(
url, HttpMethod.GET, request, RemoteUsersDTO[].class);
RemoteUsersDTO[] remoteUsers = response.getBody();
HttpHeaders responseHeaders = response.getHeaders();
List<String> links = responseHeaders.get("Link");
if (links != null) {
for (String link : links) {
if (link.contains("next")) {
String urlNext = StringUtils.substringBefore(link, ";");
urlNext = urlNext.substring(1, urlNext.length() - 1);
url = urlNext;
} else {
url = null;
}
}
} else {
url = null;
}
if (remoteUsers != null && remoteUsers.length > 0) {
remoteUserList.addAll(Arrays.asList(remoteUsers));
log.info("Total remote users from okta: " + remoteUserList.size());
} else {
url = null;
}
}
return remoteUserList;
}
然后,计算总和为15的那些:
sum_them(List,Sum) :-
foldl(sum_goal,List,0,Sum).
sum_goal(Element,FromLeft,ToRight) :-
must_be(number,Element),
must_be(number,FromLeft),
ToRight is Element+FromLeft.
可以吗?让我们编写一些单元测试:
count_them(List,Count) :-
foldl(count_goal,List,0,Count).
count_goal(Element,FromLeft,ToRight) :-
must_be(list(number),Element),
must_be(number,FromLeft),
sum_them(Element,15) -> succ(FromLeft,ToRight) ; FromLeft = ToRight.
等等:
:- begin_tests(fifteen_with_foldl).
test("first test",true(R==1)) :-
count_them([[3,10],[3,10,2],[5],[5,2],[5,3],[5,3,2],[5,3,10]],R).
test("test on empty",true(R==0)) :-
count_them([],R).
test("test with 2 hist",true(R==2)) :-
count_them([[15],[],[1,1,1,1,1,10]],R).
:- end_tests(fifteen_with_foldl).