我想在地图中使用'head'功能。 问题是'head'函数只接受非空列表。 我有清单列表:
function reqKeysToFunc( keySet, myFunc) {
var pressedKeys = {};
document.onkeydown = function(event) {
"use strict";
var myKey = event.key.toUpperCase();
//var keySet = 'ZM'; //remove this line - keySet is defined as an argument
if (keySet.search(myKey) > -1 ) {
pressedKeys[myKey] = true;
document.onkeydown = null;
if(pressedKeys.entries().filter((key, val) => val).length === keySet.length) {
myFunc();
}
}
}
}
function tmp() {
alert('hello');
}
reqKeysToFunc('ZM', tmp);
我需要迭代列表列表两次
let ll =[["dog", "cat"], ["pig", "cow"], []]
我想知道我是否可以迭代列表列表一次,或者在没有'过滤器'的情况下在地图中添加“if condition”
任何建议都将不胜感激。
答案 0 :(得分:8)
是的,实际上您可以将其编写为 list comprehension 语句,并使用模式匹配:
result = [ h | (h:_) <- ll ]
或作为一种功能:
heads :: [[a]] -> [a]
heads ll = [ h | (h:_) <- ll ]
所以我们在这里使用匹配所有非空列表的模式(h:_)
,我们直接获取此列表的头h
并将其添加到列表中。如果在列表推导中使用模式(在左箭头<-
的左侧),它将跳过与模式不匹配的元素。
这比使用length
更安全 ,因为如果使用无限列表,length
将陷入无限循环。此外,通过使用非总计head
函数的模式,我们有更多语法保证此函数可以工作(是的,一旦非空元素被过滤,我们当然可以肯定head
不会导致错误,但我们只知道这一点,因为我们有head
函数的信息。
请注意,您的尝试将导致语法错误,因为您使用if
,而没有then
和else
部分。
或者,我们可以像@DanielWagner所说的那样,以不同方式编写heads
函数,例如使用:
heads :: [[a]] -> [a]
heads ll = concatMap (take 1) ll
或使用列表monad的 bind :
heads :: [[a]] -> [a]
heads = (take 1 =<<)
或者我们可以转置2d列表。在这种情况下,第一行包含列表的所有头部。但由于不能保证有这样的行,我们可以在末尾添加一个空列表,如:
heads :: [[a]] -> [a]
heads = head . (++ [[]]) . transpose