C#-使用LINQ将带重复项的分隔字符串数组转换为字典

C#-使用LINQ将带重复项的分隔字符串数组转换为字典,c#,linq,C#,Linq,给定 我知道我可以这样把它转换成字典: string[] array = new string[] { "Sample1:foo", "Sample2:bar", "Sample1:foo1" } Dictionary which=新字典 foreach(数组中的字符串s)是否。。。 字符串sampleNumber=s.Substring(0,indexOfColon); 字符串fooOrBar=s.Substring(indexOfColon+1); 无论[sampleNu

给定

我知道我可以这样把它转换成字典:

string[] array = new string[]
{
   "Sample1:foo",
   "Sample2:bar",
   "Sample1:foo1"
}
Dictionary which=新字典
foreach(数组中的字符串s)是否。。。
字符串sampleNumber=s.Substring(0,indexOfColon);
字符串fooOrBar=s.Substring(indexOfColon+1);
无论[sampleNumber]=fooOrBar;
这将防止在添加重复键时引发聚合异常(尽管覆盖该键,在本例中这很好)。我能和LINQ一起做这个吗?我正在尝试以下几点:

Dictionary<string, string> whatever = new Dictionary<string, string>
foreach (string s in array) do...
  string sampleNumber = s.Substring(0, indexOfColon);
  string fooOrBar= s.Substring(indexOfColon + 1);
  whatever[sampleNumber] = fooOrBar;
Dictionary whatever=array.ToDictionary(
key=>key.Split(“:”)[0],value=>value.Split(“:”)[1]);
有没有一种方法可以在不事先创建查找的情况下执行此操作?

试试以下方法:

Dictionary<string, string> whatever = array.ToDictionary(
 key => key.Split(':')[0], value => value.Split(':')[1]);
字典=
排列
.Reverse()
.GroupBy(key=>key.Split(“:”)[0])
.SelectMany(x=>x.Take(1))
.ToDictionary(key=>key.Split(“:”)[0],value=>value.Split(“:”)[1]);
它给出:

或者你可以这样做:

Dictionary<string, string> whatever =
    array
        .Reverse()
        .GroupBy(key => key.Split(':')[0])
        .SelectMany(x => x.Take(1))
        .ToDictionary(key => key.Split(':')[0], value => value.Split(':')[1]);
字典=
排列
.合计(
新字典(),
(d,v)=>{d[v.Split(':')[0]]=v.Split(':')[1];返回d;});

同样的结果。

您想要的肯定不是
字典
,因为键是重复的。它可以是一本
词典
,但在我看来,它更像是一本
ILookup


我不确定你是如何处理价值的,也许你可以试试这个:

var result = array
            .Select(a =>
            {
                var parts = a.Split(':');
                return new
                {
                    Key = parts[0],
                    Value = parts[1]   //maybe you need to check something here
                };
            })
            .ToLookup(o => o.Key, o => o.Value);

我很难过没有人关心表演。浪费的分配,浪费的计算。我在50%键冲突的字符串上测试了此代码的可接受答案:

var list = array.Select(m => new { Key = m.Split(':')[0], Value = m.Split(':')[1] })
            .GroupBy(m => m.Key)
            .ToDictionary(m => m.Key, m => string.Join(",", m.Select(p => p.Value)));
char[]separatorArray={':'};//不要在数组的每个项上创建新数组
HashSet dedupll=新HashSet();
var res=数组
.Select(s=>s.Split(separatorArray))
。其中(x=>dedupll.Add(x[0]))
.ToDictionary(x=>x[0],x=>x[1]);

它大约快2.5倍,占用了一半的内存(我测量了最高内存使用量)。

工作得很好。好主意!另一种可能比使用reverse和select many更短的方法是只使用Last(),不确定时差,但
var whather=array.GroupBy(p=>p.Split(':')[0])。ToDictionary(key=>key.key,value=>value.Last().Split(':')[1])
@KeyurPATEL-我喜欢你的方法,但我确实尝试选择避免
.Last()
.First()
的选项。我知道这与
.GroupBy(…)
无关,但我喜欢保持一个好习惯。如果你想保留重复项,你可以使用
List
和一行
List whatever=array。选择(key=>newtuple(key.Split(':')[0],key.Split(':')[1])。ToList()
var list = array.Select(m => new { Key = m.Split(':')[0], Value = m.Split(':')[1] })
            .GroupBy(m => m.Key)
            .ToDictionary(m => m.Key, m => string.Join(",", m.Select(p => p.Value)));
char[] separatorArray = { ':' }; // do not create new array on every single item of the array
HashSet<string> dedupl = new HashSet<string>();

var res = array
    .Select(s => s.Split(separatorArray))
    .Where(x => dedupl.Add(x[0]))
    .ToDictionary(x => x[0], x => x[1]);