有一个像这样的字符串列表
{'123',
'234',
'345',
'123c',
'456',
'234c'}
,任务是创建list<Tuple<string><string>>
并填充每个元组,使第一个值为'x',第二个值为'xc'
例如,Tuple&lt; 123,123c&gt; ,如果没有以'c'char结尾的对,只需将第二个值置为null,就像在元组Tuple&lt; 345,null&gt;中一样。有没有办法用linq做到这一点?。
答案 0 :(得分:1)
您可以尝试这样的事情:
var result = list.GroupBy(word => !word.EndsWith('c'))
.Select(gr => Tuple.Create(gr.Key, gr.FirstOrDefault(i=>i.Contains(gr.Key))));
基本上,您可以根据列表元素进行分组,这些元素是否以字符“C&#39;”结尾。因此,您将拥有一系列键,这些键不会以字符“C&#39;”结尾。以及每个键的相关序列以及以&#39; c&#39;结尾的单词。然后按照元组的顺序投影结果,第一个元素是gropu的关键,第二个元素是以&#39; c&#39;结尾的相应值。如果它完全存在则为null,如果它不存在则为null。
答案 1 :(得分:1)
这是一个非常简单的解决方案,在分成两组后生成元组:
var firsts = strings.Where(s => !s.EndsWith("c"));
var seconds = strings.Where(s => s.EndsWith("c"));
var result = firsts.Select(f =>
new Tuple<string, string>(f, seconds.FirstOrDefault(s => s.Replace("c", "") == f)));
将代码分为以下步骤,便于阅读和理解。
答案 2 :(得分:1)
您可以按删除尾随'c'的值对所有字符串进行分组,然后根据计数是否大于1来输出元组。
这是一个使用新的Tuple语法的C#7.x / .Net 4.7解决方案:
var result = strings
.GroupBy(x => x.TrimEnd('c'))
.Select((g, v) => (g.Key, g.Count() > 1 ? g.Key+'c': null));
使用旧版本的C#和.Net:
采用相同的方法var result = strings
.GroupBy(x => x.TrimEnd('c'))
.Select((g, v) => Tuple.Create(g.Key, g.Count() > 1 ? g.Key+'c': null));
请注意,使用g.Count() > 1
来确定序列是否包含多个元素通常不如使用g.Skip(1).Any()
有效(除非基础序列是List或数组),但对于此特定应用程序将是高效的,因为集合中的项目从不超过2个。
答案 3 :(得分:0)
如果你的所有输入字符串都是一串数字,最后有一个可选的c
,你可以试试这个:
var result = list.GroupBy(x => x.TrimEnd('c'))
.Select(g => Tuple.Create(g.Key, g.FirstOrDefault(v => v.EndsWith("c"))))
这将按数字字符串对它们进行分组,最后排除任何c
,然后创建一个元组,其第一项是该数字字符串,其第二项是{{1如果它在列表中,则附加;如果没有,则附加c
。