如何将String[]
转换为IDictionary<String, String>
?
指数0,2,4,......的值应为关键字,因此指数1,3,5,......的值应为数值。
示例:
new[] { "^BI", "connectORCL", "^CR", "connectCR" }
=&GT;
new Dictionary<String, String> {{"^BI", "connectORCL"}, {"^CR", "connectCR"}};
答案 0 :(得分:11)
为了清晰起见,我建议使用旧的for循环。但是如果你坚持LINQ查询,这应该有效:
var dictionary = Enumerable.Range(0, array.Length/2)
.ToDictionary(i => array[2*i], i => array[2*i+1])
答案 1 :(得分:8)
Dictionary<string,string> ArrayToDict(string[] arr)
{
if(arr.Length%2!=0)
throw new ArgumentException("Array doesn't contain an even number of entries");
Dictionary<string,string> dict=new Dictionary<string,string>();
for(int i=0;i<arr.Length/2;i++)
{
string key=arr[2*i];
string value=arr[2*i+1];
dict.Add(key,value);
}
return dict;
}
答案 2 :(得分:6)
在LINQ中真的没有简单的方法可以做到这一点(即使有,但对于意图肯定不会很清楚)。通过一个简单的循环很容易实现:
// This code assumes you can guarantee your array to always have an even number
// of elements.
var array = new[] { "^BI", "connectORCL", "^CR", "connectCR" };
var dict = new Dictionary<string, string>();
for(int i=0; i < array.Length; i+=2)
{
dict.Add(array[i], array[i+1]);
}
答案 3 :(得分:3)
这样的事情可能是:
string[] keyValues = new string[20];
Dictionary<string, string> dict = new Dictionary<string, string>();
for (int i = 0; i < keyValues.Length; i+=2)
{
dict.Add(keyValues[i], keyValues[i + 1]);
}
编辑:C#标签中的人很快......
答案 4 :(得分:1)
如果你有Rx作为依赖,你可以这样做:
strings
.BufferWithCount(2)
.ToDictionary(
buffer => buffer.First(), // key selector
buffer => buffer.Last()); // value selector
BufferWithCount(int count)
获取输入序列中的第一个count
值并将其作为列表生成,然后它将获取下一个count
值,依此类推。即从您的输入序列中,您将得到对作为列表:{"^BI", "connectORCL"}, {"^CR", "connectCR"}
,ToDictionary
然后将第一个列表项作为键,将最后一个(= =第二个列表中的两个项)作为值。
但是,如果您不使用Rx,则可以使用BufferWithCount
:
static class EnumerableX
{
public static IEnumerable<IList<T>> BufferWithCount<T>(this IEnumerable<T> source, int count)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (count <= 0)
{
throw new ArgumentOutOfRangeException("count");
}
var buffer = new List<T>();
foreach (var t in source)
{
buffer.Add(t);
if (buffer.Count == count)
{
yield return buffer;
buffer = new List<T>();
}
}
if (buffer.Count > 0)
{
yield return buffer;
}
}
}
答案 5 :(得分:0)
看起来其他人已经打败了我和/或有更高效的答案,但我发布了两种方式:
在这种情况下,for循环可能是最明智的方法......
var words = new[] { "^BI", "connectORCL", "^CR", "connectCR" };
var final = words.Where((w, i) => i % 2 == 0)
.Select((w, i) => new[] { w, words[(i * 2) + 1] })
.ToDictionary(arr => arr[0], arr => arr[1])
;
final.Dump();
//alternate way using zip
var As = words.Where((w, i) => i % 2 == 0);
var Bs = words.Where((w, i) => i % 2 == 1);
var dictionary = new Dictionary<string, string>(As.Count());
var pairs = As.Zip(Bs, (first, second) => new[] {first, second})
.ToDictionary(arr => arr[0], arr => arr[1])
;
pairs.Dump();
答案 6 :(得分:0)
仅供参考,我最终使用循环并将其作为扩展方法实现:
internal static Boolean IsEven(this Int32 @this)
{
return @this % 2 == 0;
}
internal static IDictionary<String, String> ToDictionary(this String[] @this)
{
if (!@this.Length.IsEven())
throw new ArgumentException( "Array doesn't contain an even number of entries" );
var dictionary = new Dictionary<String, String>();
for (var i = 0; i < @this.Length; i += 2)
{
var key = @this[i];
var value = @this[i + 1];
dictionary.Add(key, value);
}
return dictionary;
}
答案 7 :(得分:0)
Pure Linq
string[] arr = new string[] { "^BI", "connectORCL", "^CR", "connectCR" };
var dictionary = arr.Select((value,i) => new {Value = value,Index = i})
.GroupBy(value => value.Index / 2)
.ToDictionary(g => g.FirstOrDefault().Value,
g => g.Skip(1).FirstOrDefault().Value);
var dictionary = arr.Select((value,i) => new {Value = value,Index = i})
.GroupBy(value => value.Index / 2)
.ToDictionary(g => g.FirstOrDefault().Value,
g => g.Skip(1).FirstOrDefault().Value);