简体   繁体   中英

System.ArgumentOutOfRangeException linq c#

I have to make a program that takes the domain for each columns.

My code is this, but when i want show throws an exception (System.ArgumentOutOfRangeException).

string[] all_lines =  {  "1, 2, 3" , "4, 5, 6", "4, 2, 3", "4, 2, 6", "9, 8, 7" };


string[] separator = new string[] { ", " };
int nAtt = all_lines[0].Split(separator, StringSplitOptions.RemoveEmptyEntries).Count() ;
List<IEnumerable> dom = new List<IEnumerable>();

for (int i = 0; i < nAtt; i++)
{
    var ele = (from lines in all_lines
                let data = lines.Split(separator, StringSplitOptions.RemoveEmptyEntries)
                select data.ElementAt(i)).Distinct();
    dom.Add(ele);
}

foreach (var row in dom)
{
    Console.Write("( ");
    foreach (var ele in row)
        Console.Write("{0} ", ele);
    Console.WriteLine(")");
}

The output of this code should be:

( 1 4 9 )
( 2 5 8 )
( 3 6 7 )

Is there any solution or alternative for this?

There is closure problem. see ElementAt(i) here.

for (int i = 0; i < nAtt; i++)
{
    var ele = (from lines in all_lines
                let data = lines.Split(separator, StringSplitOptions.RemoveEmptyEntries)
                select data.ElementAt(i)).Distinct();
    dom.Add(ele);
}

This query will use the variable i it self. its not a copy. so after loop finishes i becomes nAtt and you get exception when you try to use it. so you have to store variable before using it.

var i1 = i;
var ele = (from lines in all_lines
        let data = lines.Split(separator, StringSplitOptions.RemoveEmptyEntries)
        select data.ElementAt(i1)).Distinct();
dom.Add(ele);

Your technique is terribly inefficient because, by using .Count() and .ElementAt() repeatedly, you are reiterating your enumerables unnecessarily, many times over.

A considerably more efficient, elegant and less error-prone approach might be:

var dom = all_lines
    .SelectMany(line => line
                         .Split(new[]{", "}, StringSplitOptions.RemoveEmptyEntries)
                         .Select((x, i) => new{x, i}))
    .GroupBy(x => x.i)
    .Select(g => g.Select(gi => gi.x).Distinct())
    .ToList();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM