当我尝试使用::
运算符创建列表时,我将获得空列表。我的代码如下所示:
def getAllInfo(locks: List[String]): List[LockBundle] = DB.withTransaction { implicit s =>
val myList = List[LockBundle]()
locks.foreach(
l => findForLock(l) :: myList
)
myList
}
def findForLock(lock: String): Option[LockBundle] = { ... }
有什么建议吗?
答案 0 :(得分:8)
使用flatMap
locks.flatMap(l => findForLock(l))
您的代码变为
def getAllInfo(locks: List[String]): List[LockBundle] = DB.withTransaction { implicit s =>
locks.flatMap(l => findForLock(l))
}
或者,您可以使用map
和flatten
。像这样locks.map(l => findForLock(l)).flatten
功能编程完全是关于转换的。您只需使用您的函数findForLock
转换将现有列表转换为另一个列表。
您的代码存在问题
val myList = List[LockBundle]()
locks.foreach(
l => findForLock(l) :: myList
)
myList
首先foreach
返回Unit
因此,您使用foreach进行副作用操作而不是转换。由于您需要转换,因此请勿使用foreach
。
接下来,findForLock(l) :: myList
会为您提供一个值,但会被忽略,因为没有人存储生成的值。因此,为了存储值使用累加器并在递归的情况下将其作为函数参数传递。
更正您的代码
如果你想以自己的方式做。你需要使用累加器。
首先修复您的类型findForLock(l)
返回Option
,您的列表属于List[LockBundle]
类型,因此请将列表类型更改为List[Option[LockBundle]]
。
要从List[LockBundle]
获取List[Option[LockBundle]]
,请在flatten
列表中执行List[Option[LockBundle]]
。请参阅下面的代码段
var myList = List[Option[LockBundle]]()
locks.foreach(
l => myList = findForLock(l) :: myList
)
myList.flatten
以上方式不起作用,不推荐使用。
答案 1 :(得分:2)
您的代码不起作用,因为foreach
组合器调用每个元素的闭包,但您在此处所做的只是返回被丢弃的表达式findForLock(l) :: myList
。
正如pamu建议的那样,您可以在函数上使用flatMap
将每个元素映射到findForLock
返回的值并展平该列表,如果它是Option
,则将Some
转换为列表的元素如果是None
,则Option
或一无所获。
请注意,这只是因为存在从Seq
到flatMap
的隐式转换,通常List
只有在返回与给定monad相同的类型时才有效(这种情况为Option
或//Here's the code
typedef struct node{
bool is_word;
struct node *children[27];
} node;
unsigned int wsize=0;
node * root;
bool check(const char* word)
{
// TODO
node *chrawler=root;
for(int i=0;i<strlen(word)-1;i++)
{
int t;
if(word[i]>=65&&word[i]<=90)
{
t=word[i]-'A';
}
else if(isalpha(word[i]))
t=word[i]-'a';
else
t=26;
if(chrawler->children[t]==NULL)
return false;
else
chrawler=chrawler->children[t];
}
if(chrawler->is_word)
return true;
return false;
}
// Load function
bool load(const char* dictionary)
{
// TODO
FILE *inptr=fopen(dictionary,"r");
if(inptr==NULL)
{
return false;
}
node *new_node=malloc(sizeof(node));
root=new_node;
char * word=malloc((LENGTH+1)*sizeof(char));
int index=0;
for(int c=fgetc(inptr);c!=EOF;c=fgetc(inptr))
{
char ch=c;
if(ch=='\n')
{
word[index]='\0';
index=0;
node *chrawler=root;
for(int i=1;i<strlen(word);i++)
{
int t;
if(isalpha(word[i-1]))
t=word[i-1]-'a';
else
t=26;
if(chrawler->children[t]==NULL)
{
node *new_node=malloc(sizeof(node));
chrawler->children[t]=new_node;
chrawler=chrawler->children[t];
}
else
chrawler=chrawler->children[t];
}
chrawler->is_word=1;
wsize++;
}
else
{
word[index]=ch;
index++;
}
}
return true;
}
)。