Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将字符串[]转换为IDictionary?_C#_Linq_C# 4.0_Linq To Objects - Fatal编程技术网

C# 如何将字符串[]转换为IDictionary?

C# 如何将字符串[]转换为IDictionary?,c#,linq,c#-4.0,linq-to-objects,C#,Linq,C# 4.0,Linq To Objects,如何将字符串[]转换为IDictionary 指数0,2,4,。。。应为键,因此为索引1、3、5、,。。。应为数值 例如: new[] { "^BI", "connectORCL", "^CR", "connectCR" } => 在LINQ中真的没有简单的方法可以做到这一点,即使有,它的意图肯定不会很清楚。通过一个简单的循环即可轻松完成: // This code assumes you can guarantee your array to always have an even numb

如何将字符串[]转换为IDictionary

指数0,2,4,。。。应为键,因此为索引1、3、5、,。。。应为数值

例如:

new[] { "^BI", "connectORCL", "^CR", "connectCR" }
=>


在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]);
}

为了清晰起见,我推荐一个好的旧for循环。但是,如果您坚持使用LINQ查询,这应该是可行的:

var dictionary = Enumerable.Range(0, array.Length/2)
                           .ToDictionary(i => array[2*i], i => array[2*i+1])

可能是这样的:

        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标签中的人速度非常快…

看起来其他人已经击败了我,并且/或者有了更有效的答案,但我发布了两种方式:

在这种情况下,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();

仅供参考,这就是我使用循环并将其作为扩展方法实现的结果:

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;
}
如果您有依赖项,则可以执行以下操作:

strings
    .BufferWithCount(2)
    .ToDictionary(
         buffer => buffer.First(), // key selector
         buffer => buffer.Last()); // value selector
BufferWithCountint count从输入序列中获取第一个计数值,并将其作为列表生成,然后获取下一个计数值,依此类推。也就是说,从您的输入序列中,您将获得作为列表的对:{^BI,connectORCL},{^CR,connectCR},ToDictionary然后将第一个列表项作为键,最后==第二个列表项作为值

但是,如果不使用Rx,则可以使用BufferWithCount的此实现:

纯林克

选择:项目原始字符串值及其索引。 GroupBy:将相邻对分组。 将每个组转换为字典条目。 字符串[]arr=新字符串[]{^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);

这类似于但不是的副本:如果您需要多次这样做,我建议您将您最喜欢的答案提取到扩展方法IDictionary to dictionary This string[]arr@HuBeZa:在我看到你的评论之前完成-C标签就像古老的西部。一定要迅速抽签。这是我的。你可以用LINQ来做,但我发现一个简单的for循环在这种情况下更具可读性和明显性。@Anthony Pegram-你说得对。通过使用Enumerable.Range创建另一个集合,可以使用LINQ。我对你的答案投了更高的票,同意for循环更为清晰。唯一的缺点是你正在通过Enumerable.Range强制创建另一个集合。我想说的是,另一个缺点是这非常难看,很难阅读,正如他所建议的那样。@Justin:开销应该是最小的,因为Enumerable.Range是惰性地计算的。两个对象enumerable+enumerator和一些整数base、count和max.+1,用于显示linq方式并表示可读性受到+1的影响,谢谢。我现在不引用Rx,但会尽量记住这一个。
strings
    .BufferWithCount(2)
    .ToDictionary(
         buffer => buffer.First(), // key selector
         buffer => buffer.Last()); // value selector
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;
        }
    }
}
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);