我在C#中有一个LINQ Joining语句,我试图通过两个字符串列表来查找结构列表:
public struct ll
{
public int index;
public string one;
public string two;
}
public List <ll> list1; //{"0,a, ", "1,," , "2,a,dog" , "3,,horse"}
public List <string> list2; //{"a","b"}
public List <string> list3; //{"cat","mouse","dog"}
这个想法是在list1中并不是所有的结构都包含一个值,所以在索引0上只有list1.one的值是&#34; a&#34;,list1.two是空的。在索引1上,list1.one和list1.two都是空的。在索引2上,list1.one和list.two都有值。在索引3上只有list.two有一个值。
下面我试图加入这三个列表
var query = from x in list1
join y1 in list2 on x.one equals y1
join y2 in list3 on x.two equals y2
select x.index;
使用此语句,只有list1.one匹配list2中的项目并且list1.two匹配list2中的项目时才会进行连接。 但是我想看到的是,如果只填充了list1.one,但list1.two为空,则join只会将list2中的项目与list1.one匹配,但会加入list3中的所有项目,因此空的list1.two不在帐户中。
编辑:
让我重新解释一下这个问题。我的目标是该程序读取用户输入的句子,将不定式,名词,文章和副词存储在单独的列表中,并尝试根据所有列表的连接为用户找到最佳答案或答复。
所以list1看起来应该是
public struct ll
{
int index;
string infinitive;
string noun;
string article;
string adverb;
string answer;
}
public List <ll> list1;
以下数据:
例如,当用户输入句子时,你能找到什么&#39;连接脚本应该返回两个可能的答案:
&#34;我可以找到这些信息&#34;和#34;你希望我找到什么&#34;
关于句子&#34;你能在这里找到什么&#34;
它只会返回: &#34;我可以找到这些信息&#34;
但当用户问:&#34;你对这个霍比特人有什么了解&#34;它将不会返回任何组合&#34;知道&#34;和&#34;这个&#34;是不知道的,在哪里&#34;你对霍比特人有什么了解&#34;将返回&#34;我知道&#34;
希望这更清楚知道
答案 0 :(得分:0)
很难确切地说出你想要什么,特别是如何定义index
,但我猜是这样的。您希望l1
成为每个域的搜索字词的某种输入列表,并且您希望l2
,l3
等成为某种搜索域。
JOIN
不是解决这个问题的正确方法。您只是希望通过输入进行线性搜索,以进行域匹配。你可以很好地抽象出来,而不是让每个域都是它自己的列表,只需将它列为列表列表,然后按顺序搜索。具体如下:
var lists = new[]
{
new[] { "a", null },
new string[] { null, null },
new[] { "a", "dog" },
new[] { null, "horse" }
};
var domains = new[] { new[] { "a", "b" }, new[] { "cat", "mouse", "dog" } };
var matches = lists.Where(list => list.Where((s, i) => s == null || domains[i].Contains(s)).Count() == list.Length);
foreach (var list in matches)
{
Console.WriteLine(string.Join(",", list));
}
输出:
"a",null
null,null
"a","dog"
当然,您可以编写一个函数来确定index
中每个列表的相应matches
值,如果这是您最终需要的。我建议你重新定义你的index
是一个有点标志,而不是你描述的临时方式;那么你可以这样做:
static int GetIndex<T>(IEnumerable<T> list)
{
return list.Select((s, i) => s == null ? 0 : 1 << i).Sum();
}
或者,如果您想内联所有内容,那么它只是
var indices = lists.Where(list => list.Where((s, i) => s == null || domains[i].Contains(s)).Count() == list.Length)
.Select(list => list.Select((s, i) => s == null ? 0 : 1 << i).Sum())
.Distinct();
或者,如果您定义一个好的帮助程序索引 - 所有LINQ函数,那么它可能会更清楚:
public static bool All<T>(this IEnumerable<T> seq, Func<T, int, bool> pred)
{
return seq.Select((x, i) => Tuple.Create(x, i)).All(t => pred(t.Item1, t.Item2));
}
...
IEnumerable<int> indices = lists
.Where(list => list.All((s, i) => s == null || domains[i].Contains(s)))
.Select(list => list.Select((s, i) => s == null ? 0 : 1 << i).Sum())
.Distinct();