1

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?

1
  • 3
    there can be alternatives, if you explain what this code is supposed to do. which output it should produce? Commented Nov 23, 2015 at 18:08

2 Answers 2

4

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);
Sign up to request clarification or add additional context in comments.

Comments

1

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();

5 Comments

@M.kazemAkhgary I got it when they showed us the desired output. Was tricky to spot the pattern though!
but also keeps the comma
@JesusPerezLimon. Um. No it doesn't. What makes you think that?
This has the benefit of working even if the number of comma separated values in each "line" is different.
my fault, it's perfect

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.