简体   繁体   中英

Iterate over items in Tuple

I have this method with three loops:

    public void Print(Tuple<List<DateTime>, List<double>, List<string>> dataToPrint)
    {
        foreach (var item in dataToPrint.Item1)
        {
            Console.WriteLine(item);
        }
        foreach (var item in dataToPrint.Item2)
        {
            Console.WriteLine(item);
        }
        foreach (var item in dataToPrint.Item3)
        {
            Console.WriteLine(item);
        }
    }

Is it possible to use only one loop to print all the items with contents of the Lists on the screen?

You can, of course, concat all lists into one sequence of object or string items, but this concatenation will not make your code more readable. But you can create simple extension method which dumps content of any sequence to the console:

public static void Dump<T>(this IEnumerable<T> source)
{
    foreach(var item in source)
       Console.WriteLine(item);
}

And your code will look like (no loops at all):

public void Print(Tuple<List<DateTime>, List<double>, List<string>> dataToPrint)
{
    dataToPrint.Item1.Dump();
    dataToPrint.Item2.Dump();
    dataToPrint.Item3.Dump();
}

I would also use named parameters, custom type or value tuple to pass these three values to the method.

Yes, but you have to be sure that all lists have the same length.
You could basically do something like this:

for (var i = 0; i < dataToPrint.Item1.Length; i++)
{
    Console.WriteLine(dataToPrint.Item1[i]);
    Console.WriteLine(dataToPrint.Item2[i]);
    Console.WriteLine(dataToPrint.Item3[i]);
}

Edit: Calling ForEach(Console.WriteLine) on a list of datetimes won't actually work as Console.WriteLine does not have a specific override that takes a date time it just uses the override that takes an object. Since List.ForEach expects an Action and the Console.WriteLine method required to write a datetime is infact an Action this code wont compile, so this answer isn't correct. However I think its pretty interesting to see why it wont work, so I'll leave it here

I'm not sure really why you have a problem with the code there. If that is the signature of the method and you can't change it then that to me seems valid. If you for some reason really want to limit your lines code you can do this

dataToPrint.Item1.ForEach(Console.WriteLine);
dataToPrint.Item2.ForEach(Console.WriteLine);
dataToPrint.Item3.ForEach(Console.WriteLine);

Some others have suggested a for loop of all the lists are the same length but this will print out in a different order to what you have described. And cast all the items in all the lists into objects so you can contat the lists could be costly thanks to boxing your value types like double. Edit: I've been informed that the boxing is probably negligible compared to the performance of writing to then console. However I still think casting them all to object isnt the best option, but that's just me

try this:

foreach (var element in dataToPrint.Item1.Cast<object>().Concat(dataToPrint.Item2.Cast<object>()).Concat(dataToPrint.Item3.Cast<object>()))
{
    Console.WriteLine(element);
}

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