Related
I frequently find myself writing code like this:
List<int> list = new List<int> { 1, 3, 5 };
foreach (int i in list) {
Console.Write("{0}\t", i.ToString()); }
Console.WriteLine();
Better would be something like this:
List<int> list = new List<int> { 1, 3, 5 };
Console.WriteLine("{0}\t", list);
I suspect there's some clever way of doing this, but I don't see it. Does anybody have a better solution than the first block?
Do this:
list.ForEach(i => Console.Write("{0}\t", i));
EDIT: To others that have responded - he wants them all on the same line, with tabs between them. :)
A different approach, just for kicks:
Console.WriteLine(string.Join("\t", list));
new List<int> { 1, 3, 5 }.ForEach(Console.WriteLine);
If there is a piece of code that you repeat all the time according to Don't Repeat Yourself you should put it in your own library and call that. With that in mind there are 2 aspects to getting the right answer here. The first is clarity and brevity in the code that calls the library function. The second is the performance implications of foreach.
First let's think about the clarity and brevity in the calling code.
You can do foreach in a number of ways:
for loop
foreach loop
Collection.ForEach
Out of all the ways to do a foreach List.ForEach with a lamba is the clearest and briefest.
list.ForEach(i => Console.Write("{0}\t", i));
So at this stage it may look like the List.ForEach is the way to go. However what's the performance of this? It's true that in this case the time to write to the console will govern the performance of the code. When we know something about performance of a particular language feature we should certainly at least consider it.
According to Duston Campbell's performance measurements of foreach the fastest way of iterating the list under optimised code is using a for loop without a call to List.Count.
The for loop however is a verbose construct. It's also seen as a very iterative way of doing things which doesn't match with the current trend towards functional idioms.
So can we get brevity, clarity and performance? We can by using an extension method. In an ideal world we would create an extension method on Console that takes a list and writes it with a delimiter. We can't do this because Console is a static class and extension methods only work on instances of classes. Instead we need to put the extension method on the list itself (as per David B's suggestion):
public static void WriteLine(this List<int> theList)
{
foreach (int i in list)
{
Console.Write("{0}\t", t.ToString());
}
Console.WriteLine();
}
This code is going to used in many places so we should carry out the following improvements:
Instead of using foreach we should use the fastest way of iterating the collection which is a for loop with a cached count.
Currently only List can be passed as an argument. As a library function we can generalise it through a small amount of effort.
Using List limits us to just Lists, Using IList allows this code to work with Arrays too.
Since the extension method will be on an IList we need to change the name to make it clearer what we are writing to:
Here's how the code for the function would look:
public static void WriteToConsole<T>(this IList<T> collection)
{
int count = collection.Count();
for(int i = 0; i < count; ++i)
{
Console.Write("{0}\t", collection[i].ToString(), delimiter);
}
Console.WriteLine();
}
We can improve this even further by allowing the client to pass in the delimiter. We could then provide a second function that writes to console with the standard delimiter like this:
public static void WriteToConsole<T>(this IList<T> collection)
{
WriteToConsole<T>(collection, "\t");
}
public static void WriteToConsole<T>(this IList<T> collection, string delimiter)
{
int count = collection.Count();
for(int i = 0; i < count; ++i)
{
Console.Write("{0}{1}", collection[i].ToString(), delimiter);
}
Console.WriteLine();
}
So now, given that we want a brief, clear performant way of writing lists to the console we have one. Here is entire source code including a demonstration of using the the library function:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleWritelineTest
{
public static class Extensions
{
public static void WriteToConsole<T>(this IList<T> collection)
{
WriteToConsole<T>(collection, "\t");
}
public static void WriteToConsole<T>(this IList<T> collection, string delimiter)
{
int count = collection.Count();
for(int i = 0; i < count; ++i)
{
Console.Write("{0}{1}", collection[i].ToString(), delimiter);
}
Console.WriteLine();
}
}
internal class Foo
{
override public string ToString()
{
return "FooClass";
}
}
internal class Program
{
static void Main(string[] args)
{
var myIntList = new List<int> {1, 2, 3, 4, 5};
var myDoubleList = new List<double> {1.1, 2.2, 3.3, 4.4};
var myDoubleArray = new Double[] {12.3, 12.4, 12.5, 12.6};
var myFooList = new List<Foo> {new Foo(), new Foo(), new Foo()};
// Using the standard delimiter /t
myIntList.WriteToConsole();
myDoubleList.WriteToConsole();
myDoubleArray.WriteToConsole();
myFooList.WriteToConsole();
// Using our own delimiter ~
myIntList.WriteToConsole("~");
Console.Read();
}
}
}
=======================================================
You might think that this should be the end of the answer. However there is a further piece of generalisation that can be done. It's not clear from fatcat's question if he is always writing to the console. Perhaps something else is to be done in the foreach. In that case Jason Bunting's answer is going to give that generality. Here is his answer again:
list.ForEach(i => Console.Write("{0}\t", i));
That is unless we make one more refinement to our extension methods and add FastForEach as below:
public static void FastForEach<T>(this IList<T> collection, Action<T> actionToPerform)
{
int count = collection.Count();
for (int i = 0; i < count; ++i)
{
actionToPerform(collection[i]);
}
Console.WriteLine();
}
This allows us to execute any arbitrary code against every element in the collection using the fastest possible iteration method.
We can even change the WriteToConsole function to use FastForEach
public static void WriteToConsole<T>(this IList<T> collection, string delimiter)
{
collection.FastForEach(item => Console.Write("{0}{1}", item.ToString(), delimiter));
}
So now the entire source code, including an example usage of FastForEach is:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleWritelineTest
{
public static class Extensions
{
public static void WriteToConsole<T>(this IList<T> collection)
{
WriteToConsole<T>(collection, "\t");
}
public static void WriteToConsole<T>(this IList<T> collection, string delimiter)
{
collection.FastForEach(item => Console.Write("{0}{1}", item.ToString(), delimiter));
}
public static void FastForEach<T>(this IList<T> collection, Action<T> actionToPerform)
{
int count = collection.Count();
for (int i = 0; i < count; ++i)
{
actionToPerform(collection[i]);
}
Console.WriteLine();
}
}
internal class Foo
{
override public string ToString()
{
return "FooClass";
}
}
internal class Program
{
static void Main(string[] args)
{
var myIntList = new List<int> {1, 2, 3, 4, 5};
var myDoubleList = new List<double> {1.1, 2.2, 3.3, 4.4};
var myDoubleArray = new Double[] {12.3, 12.4, 12.5, 12.6};
var myFooList = new List<Foo> {new Foo(), new Foo(), new Foo()};
// Using the standard delimiter /t
myIntList.WriteToConsole();
myDoubleList.WriteToConsole();
myDoubleArray.WriteToConsole();
myFooList.WriteToConsole();
// Using our own delimiter ~
myIntList.WriteToConsole("~");
// What if we want to write them to separate lines?
myIntList.FastForEach(item => Console.WriteLine(item.ToString()));
Console.Read();
}
}
}
List<int> list = new List<int> { 1, 3, 5 };
list.ForEach(x => Console.WriteLine(x));
Edit: Dammit! took too long to open visual studio to test it.
List<int> a = new List<int>() { 1, 2, 3, 4, 5 };
a.ForEach(p => Console.WriteLine(p));
edit: ahhh he beat me to it.
list.ForEach(x=>Console.WriteLine(x));
Also you can do join:
var qwe = new List<int> {5, 2, 3, 8};
Console.WriteLine(string.Join("\t", qwe));
public static void WriteLine(this List<int> theList)
{
foreach (int i in list)
{
Console.Write("{0}\t", t.ToString());
}
Console.WriteLine();
}
Then, later...
list.WriteLine();
I have a string array, I need to delete all elements until a specific index or get a new array of all elements from my specific index. I'm looking for a system function without loops.
my code for example:
string []myArray = {"AAA","BBB","CCC","DDD","EEE","FFF","GGG","HHH"}
int myIndex = Array.IndexOf(myArray, "DDD");
needed output :
string []myNewArray = {"EEE","FFF","GGG","HHH"}
Just use Skip in Linq
string []myArray = {"AAA","BBB","CCC","DDD","EEE","FFF","GGG","HHH"}
int myIndex = Array.IndexOf(myArray, "DDD");
var newArray = myArray.Skip(myIndex+1);
Of course this means only that the loop is hidden from your view, but it exits nevertheless inside the Skip method.
Also, the code above, will return the whole array if the search for the string is unsuccessful.
You can use Linq's SkipWhile
string[] myArray = { "AAA", "BBB", "CCC", "DDD", "EEE", "FFF", "GGG", "HHH" };
var myNewArray = myArray.SkipWhile(x => x != "DDD").Skip(1).ToArray();
Arrays are a pretty "dumb" object, as they mostly just have methods that effectively describe themselves. What you'll want to do is make it Queryable (one of its methods), then use LINQ to do it.
string[] myarray = GimmeAStringArray();
int x = desiredIndexValue;
return myarray.AsQueryable().Where(t => myarray.IndexOf(t) > x);
You might not need to AsQueryable() it to do that.
there is another simple way to do that using arrayList:
you can use method arraylist.RemoveRange(start index, last index)
public static void Main()
{
string[] array = new string[] {"AAA","BBB","CCC","DDD","EEE","FFF","GGG","HHH"};
List<string> list = new List<string>(array);
list.RemoveRange(0,list.IndexOf("DDD")+1);
foreach (string str in list)
{
Console.WriteLine(str);
}
}
output of program will be :
EEE
FFF
GGG
HHH
I have a generic list of string[] arrays, and I need to build a list of strings with all possible combinations of the items in those arrays. I'm having a hard time wrapping my head around the best method.
so:
List mylist = new List; // I then populate this from the db...
The contents of mylist looks like this:
Buildings ||| Facilities ||| Fields ||| Files; Groups; Entity; ||| Controllers; FX; Steam;
The pipes " ||| " separate each string array in mylist, the semicolons are delimiters representing the items within each of those arrays. So the arrays have a minimum length of 1, and a max of N. I need to build a list of hyphen "---" separated strings with all possible combinations of the above, but staying in the order that they are in within the list. So using the above as an example, I would come up with this list of strings:
Buildings---Facilities---fields---Files---Controllers
Buildings---Facilities---fields---Groups---Controllers
Buildings---Facilities---fields---Entity---Controllers
Buildings---Facilities---fields---Files---Fx
Buildings---Facilities---fields---Groups---Fx
Buildings---Facilities---fields---Entity---Fx
Buildings---Facilities---fields---Files---Steam
Buildings---Facilities---fields---Groups---Steam
Buildings---Facilities---fields---Entity---Steam
If the 3rd array in the list had 2 items, instead of 1 ("Fields") - we'd have a list of 18 strings instead of 9 (3x3x2).
I tried using for loops, knowing which array had the largest length, and loop through each list item, but I just couldn't get it to work. Sleeping on it didn't really help.
anyone?
I would try recursion:
private void button1_Click(object sender, EventArgs e)
{
List<string[]> strs = new List<string[]>();
strs.Add(new string[] {"Buildings"});
strs.Add(new string[] {"Facilities"});
strs.Add(new string[] {"Fields"});
strs.Add(new string[] {"Files", "Groups", "Entity"});
strs.Add(new string[] {"Controllers", "FX", "Steam"});
List<string> list = AddStringsToList(strs, 0);
}
List<string> AddStringsToList(List<string[]> list, int level)
{
List<string> listOfStrings = new List<string>();
if (level == list.Count - 1)
{
foreach (string s in list[level])
{
listOfStrings.Add(s);
}
}
else if(level<list.Count-1)
{
List<string> list1 = AddStringsToList(list, level + 1);
foreach (string s in list[level])
{
foreach(string s1 in list1)
listOfStrings.Add(s + "---" + s1);
}
}
return listOfStrings;
}
Tested and it works!
I think this might do what you're looking for:
static IEnumerable<string> Combinations(IEnumerable<IEnumerable<string>> items)
{
return items.Aggregate((outs, ins) => outs.SelectMany(o => ins.Select(i => o + "---" + i)));
}
And here is an example usage
static void Main(string[] args)
{
IEnumerable<IEnumerable<string>> items = new string[][]
{
new [] { "Buildings" },
new [] { "Facilities" },
new [] { "Fields" },
new [] { "Files", "Groups", "Entity" },
new [] { "Controllers", "FX", "Steam" }
};
foreach (var c in Combinations(items))
Console.WriteLine(c);
Console.ReadLine();
}
For each set of possibilities, it takes all the strings it has so far (for example "Buildings---Facilities---fields---Files", "Buildings---Facilities---fields---Entity" etc), and then for each possibility (eg { "Controllers", "FX", "Steam"}) it appends that possibility to the the output string to get a new set of output strings. The aggregation iterates this process starting at just the possibilities for the first element as the output strings, and then repeating this "Cartesian product" successively until all the input is consumed.
Edit
For reference this is the output from the sample program:
Buildings---Facilities---Fields---Files---Controllers
Buildings---Facilities---Fields---Files---FX
Buildings---Facilities---Fields---Files---Steam
Buildings---Facilities---Fields---Groups---Controllers
Buildings---Facilities---Fields---Groups---FX
Buildings---Facilities---Fields---Groups---Steam
Buildings---Facilities---Fields---Entity---Controllers
Buildings---Facilities---Fields---Entity---FX
Buildings---Facilities---Fields---Entity---Steam
I'd like to point out that this solution is quite efficient. It doesn't use recursion, which makes it particularly efficient for cases with long chains. Also, it evaluates the result lazily which is much more memory efficient if you're dealing with many result combinations (remember these combinations can grow exponentially with the chain length).
Let's produce this instead:
Buildings---Facilities---fields---Files---Controllers
Buildings---Facilities---fields---Files---Fx
Buildings---Facilities---fields---Files---Steam
Buildings---Facilities---fields---Groups---Controllers
Buildings---Facilities---fields---Groups---Fx
Buildings---Facilities---fields---Groups---Steam
Buildings---Facilities---fields---Entity---Controllers
Buildings---Facilities---fields---Entity---Fx
Buildings---Facilities---fields---Entity---Steam
First, let's assume the data from the DB is in this format:
List<List<string>> dataFromDb;
It doesn't matter if some of the inner collections only have one value. Then something like this should do the trick:
void ConcatString(string prefix, int index, List<List<string>> collection, List<string> output)
{
if(index == collection.Count)
{
output.Add(prefix);
return;
}
var subCollection = collection[index];
foreach(var str in subCollection)
{
string newPrefix = ((prefix.Length > 0)? "---" : "") + str;
ConcatString(newPrefix, index+1, collection, output);
}
}
Called like:
var output = new List<string>();
ConcatString("", 0, dataFromDb, output);
The list you're looking for should be in output. Now, please note, I haven't run this (heck, I haven't even compiled this) so you'll need to debug it but it should get you going in the correct direction at a minimum.
Context: C# 3.0, .Net 3.5
Suppose I have a method that generates random numbers (forever):
private static IEnumerable<int> RandomNumberGenerator() {
while (true) yield return GenerateRandomNumber(0, 100);
}
I need to group those numbers in groups of 10, so I would like something like:
foreach (IEnumerable<int> group in RandomNumberGenerator().Slice(10)) {
Assert.That(group.Count() == 10);
}
I have defined Slice method, but I feel there should be one already defined. Here is my Slice method, just for reference:
private static IEnumerable<T[]> Slice<T>(IEnumerable<T> enumerable, int size) {
var result = new List<T>(size);
foreach (var item in enumerable) {
result.Add(item);
if (result.Count == size) {
yield return result.ToArray();
result.Clear();
}
}
}
Question: is there an easier way to accomplish what I'm trying to do? Perhaps Linq?
Note: above example is a simplification, in my program I have an Iterator that scans given matrix in a non-linear fashion.
EDIT: Why Skip+Take is no good.
Effectively what I want is:
var group1 = RandomNumberGenerator().Skip(0).Take(10);
var group2 = RandomNumberGenerator().Skip(10).Take(10);
var group3 = RandomNumberGenerator().Skip(20).Take(10);
var group4 = RandomNumberGenerator().Skip(30).Take(10);
without the overhead of regenerating number (10+20+30+40) times. I need a solution that will generate exactly 40 numbers and break those in 4 groups by 10.
Are Skip and Take of any use to you?
Use a combination of the two in a loop to get what you want.
So,
list.Skip(10).Take(10);
Skips the first 10 records and then takes the next 10.
I have done something similar. But I would like it to be simpler:
//Remove "this" if you don't want it to be a extension method
public static IEnumerable<IList<T>> Chunks<T>(this IEnumerable<T> xs, int size)
{
var curr = new List<T>(size);
foreach (var x in xs)
{
curr.Add(x);
if (curr.Count == size)
{
yield return curr;
curr = new List<T>(size);
}
}
}
I think yours are flawed. You return the same array for all your chunks/slices so only the last chunk/slice you take would have the correct data.
Addition: Array version:
public static IEnumerable<T[]> Chunks<T>(this IEnumerable<T> xs, int size)
{
var curr = new T[size];
int i = 0;
foreach (var x in xs)
{
curr[i % size] = x;
if (++i % size == 0)
{
yield return curr;
curr = new T[size];
}
}
}
Addition: Linq version (not C# 2.0). As pointed out, it will not work on infinite sequences and will be a great deal slower than the alternatives:
public static IEnumerable<T[]> Chunks<T>(this IEnumerable<T> xs, int size)
{
return xs.Select((x, i) => new { x, i })
.GroupBy(xi => xi.i / size, xi => xi.x)
.Select(g => g.ToArray());
}
Using Skip and Take would be a very bad idea. Calling Skip on an indexed collection may be fine, but calling it on any arbitrary IEnumerable<T> is liable to result in enumeration over the number of elements skipped, which means that if you're calling it repeatedly you're enumerating over the sequence an order of magnitude more times than you need to be.
Complain of "premature optimization" all you want; but that is just ridiculous.
I think your Slice method is about as good as it gets. I was going to suggest a different approach that would provide deferred execution and obviate the intermediate array allocation, but that is a dangerous game to play (i.e., if you try something like ToList on such a resulting IEnumerable<T> implementation, without enumerating over the inner collections, you'll end up in an endless loop).
(I've removed what was originally here, as the OP's improvements since posting the question have since rendered my suggestions here redundant.)
Let's see if you even need the complexity of Slice. If your random number generates is stateless, I would assume each call to it would generate unique random numbers, so perhaps this would be sufficient:
var group1 = RandomNumberGenerator().Take(10);
var group2 = RandomNumberGenerator().Take(10);
var group3 = RandomNumberGenerator().Take(10);
var group4 = RandomNumberGenerator().Take(10);
Each call to Take returns a new group of 10 numbers.
Now, if your random number generator re-seeds itself with a specific value each time it's iterated, this won't work. You'll simply get the same 10 values for each group. So instead, you would use:
var generator = RandomNumberGenerator();
var group1 = generator.Take(10);
var group2 = generator.Take(10);
var group3 = generator.Take(10);
var group4 = generator.Take(10);
This maintains an instance of the generator so that you can continue retrieving values without re-seeding the generator.
You could use the Skip and Take methods with any Enumerable object.
For your edit :
How about a function that takes a slice number and a slice size as a parameter?
private static IEnumerable<T> Slice<T>(IEnumerable<T> enumerable, int sliceSize, int sliceNumber) {
return enumerable.Skip(sliceSize * sliceNumber).Take(sliceSize);
}
It seems like we'd prefer for an IEnumerable<T> to have a fixed position counter so that we can do
var group1 = items.Take(10);
var group2 = items.Take(10);
var group3 = items.Take(10);
var group4 = items.Take(10);
and get successive slices rather than getting the first 10 items each time. We can do that with a new implementation of IEnumerable<T> which keeps one instance of its Enumerator and returns it on every call of GetEnumerator:
public class StickyEnumerable<T> : IEnumerable<T>, IDisposable
{
private IEnumerator<T> innerEnumerator;
public StickyEnumerable( IEnumerable<T> items )
{
innerEnumerator = items.GetEnumerator();
}
public IEnumerator<T> GetEnumerator()
{
return innerEnumerator;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return innerEnumerator;
}
public void Dispose()
{
if (innerEnumerator != null)
{
innerEnumerator.Dispose();
}
}
}
Given that class, we could implement Slice with
public static IEnumerable<IEnumerable<T>> Slices<T>(this IEnumerable<T> items, int size)
{
using (StickyEnumerable<T> sticky = new StickyEnumerable<T>(items))
{
IEnumerable<T> slice;
do
{
slice = sticky.Take(size).ToList();
yield return slice;
} while (slice.Count() == size);
}
yield break;
}
That works in this case, but StickyEnumerable<T> is generally a dangerous class to have around if the consuming code isn't expecting it. For example,
using (var sticky = new StickyEnumerable<int>(Enumerable.Range(1, 10)))
{
var first = sticky.Take(2);
var second = sticky.Take(2);
foreach (int i in second)
{
Console.WriteLine(i);
}
foreach (int i in first)
{
Console.WriteLine(i);
}
}
prints
1
2
3
4
rather than
3
4
1
2
Take a look at Take(), TakeWhile() and Skip()
I think the use of Slice() would be a bit misleading. I think of that as a means to give me a chuck of an array into a new array and not causing side effects. In this scenario you would actually move the enumerable forward 10.
A possible better approach is to just use the Linq extension Take(). I don't think you would need to use Skip() with a generator.
Edit: Dang, I have been trying to test this behavior with the following code
Note: this is wasn't really correct, I leave it here so others don't fall into the same mistake.
var numbers = RandomNumberGenerator();
var slice = numbers.Take(10);
public static IEnumerable<int> RandomNumberGenerator()
{
yield return random.Next();
}
but the Count() for slice is alway 1. I also tried running it through a foreach loop since I know that the Linq extensions are generally lazily evaluated and it only looped once. I eventually did the code below instead of the Take() and it works:
public static IEnumerable<int> Slice(this IEnumerable<int> enumerable, int size)
{
var list = new List<int>();
foreach (var count in Enumerable.Range(0, size)) list.Add(enumerable.First());
return list;
}
If you notice I am adding the First() to the list each time, but since the enumerable that is being passed in is the generator from RandomNumberGenerator() the result is different every time.
So again with a generator using Skip() is not needed since the result will be different. Looping over an IEnumerable is not always side effect free.
Edit: I'll leave the last edit just so no one falls into the same mistake, but it worked fine for me just doing this:
var numbers = RandomNumberGenerator();
var slice1 = numbers.Take(10);
var slice2 = numbers.Take(10);
The two slices were different.
I had made some mistakes in my original answer but some of the points still stand. Skip() and Take() are not going to work the same with a generator as it would a list. Looping over an IEnumerable is not always side effect free. Anyway here is my take on getting a list of slices.
public static IEnumerable<int> RandomNumberGenerator()
{
while(true) yield return random.Next();
}
public static IEnumerable<IEnumerable<int>> Slice(this IEnumerable<int> enumerable, int size, int count)
{
var slices = new List<List<int>>();
foreach (var iteration in Enumerable.Range(0, count)){
var list = new List<int>();
list.AddRange(enumerable.Take(size));
slices.Add(list);
}
return slices;
}
I got this solution for the same problem:
int[] ints = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
IEnumerable<IEnumerable<int>> chunks = Chunk(ints, 2, t => t.Dump());
//won't enumerate, so won't do anything unless you force it:
chunks.ToList();
IEnumerable<T> Chunk<T, R>(IEnumerable<R> src, int n, Func<IEnumerable<R>, T> action){
IEnumerable<R> head;
IEnumerable<R> tail = src;
while (tail.Any())
{
head = tail.Take(n);
tail = tail.Skip(n);
yield return action(head);
}
}
if you just want the chunks returned, not do anything with them, use chunks = Chunk(ints, 2, t => t). What I would really like is to have to have t=>t as default action, but I haven't found out how to do that yet.
I frequently find myself writing code like this:
List<int> list = new List<int> { 1, 3, 5 };
foreach (int i in list) {
Console.Write("{0}\t", i.ToString()); }
Console.WriteLine();
Better would be something like this:
List<int> list = new List<int> { 1, 3, 5 };
Console.WriteLine("{0}\t", list);
I suspect there's some clever way of doing this, but I don't see it. Does anybody have a better solution than the first block?
Do this:
list.ForEach(i => Console.Write("{0}\t", i));
EDIT: To others that have responded - he wants them all on the same line, with tabs between them. :)
A different approach, just for kicks:
Console.WriteLine(string.Join("\t", list));
new List<int> { 1, 3, 5 }.ForEach(Console.WriteLine);
If there is a piece of code that you repeat all the time according to Don't Repeat Yourself you should put it in your own library and call that. With that in mind there are 2 aspects to getting the right answer here. The first is clarity and brevity in the code that calls the library function. The second is the performance implications of foreach.
First let's think about the clarity and brevity in the calling code.
You can do foreach in a number of ways:
for loop
foreach loop
Collection.ForEach
Out of all the ways to do a foreach List.ForEach with a lamba is the clearest and briefest.
list.ForEach(i => Console.Write("{0}\t", i));
So at this stage it may look like the List.ForEach is the way to go. However what's the performance of this? It's true that in this case the time to write to the console will govern the performance of the code. When we know something about performance of a particular language feature we should certainly at least consider it.
According to Duston Campbell's performance measurements of foreach the fastest way of iterating the list under optimised code is using a for loop without a call to List.Count.
The for loop however is a verbose construct. It's also seen as a very iterative way of doing things which doesn't match with the current trend towards functional idioms.
So can we get brevity, clarity and performance? We can by using an extension method. In an ideal world we would create an extension method on Console that takes a list and writes it with a delimiter. We can't do this because Console is a static class and extension methods only work on instances of classes. Instead we need to put the extension method on the list itself (as per David B's suggestion):
public static void WriteLine(this List<int> theList)
{
foreach (int i in list)
{
Console.Write("{0}\t", t.ToString());
}
Console.WriteLine();
}
This code is going to used in many places so we should carry out the following improvements:
Instead of using foreach we should use the fastest way of iterating the collection which is a for loop with a cached count.
Currently only List can be passed as an argument. As a library function we can generalise it through a small amount of effort.
Using List limits us to just Lists, Using IList allows this code to work with Arrays too.
Since the extension method will be on an IList we need to change the name to make it clearer what we are writing to:
Here's how the code for the function would look:
public static void WriteToConsole<T>(this IList<T> collection)
{
int count = collection.Count();
for(int i = 0; i < count; ++i)
{
Console.Write("{0}\t", collection[i].ToString(), delimiter);
}
Console.WriteLine();
}
We can improve this even further by allowing the client to pass in the delimiter. We could then provide a second function that writes to console with the standard delimiter like this:
public static void WriteToConsole<T>(this IList<T> collection)
{
WriteToConsole<T>(collection, "\t");
}
public static void WriteToConsole<T>(this IList<T> collection, string delimiter)
{
int count = collection.Count();
for(int i = 0; i < count; ++i)
{
Console.Write("{0}{1}", collection[i].ToString(), delimiter);
}
Console.WriteLine();
}
So now, given that we want a brief, clear performant way of writing lists to the console we have one. Here is entire source code including a demonstration of using the the library function:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleWritelineTest
{
public static class Extensions
{
public static void WriteToConsole<T>(this IList<T> collection)
{
WriteToConsole<T>(collection, "\t");
}
public static void WriteToConsole<T>(this IList<T> collection, string delimiter)
{
int count = collection.Count();
for(int i = 0; i < count; ++i)
{
Console.Write("{0}{1}", collection[i].ToString(), delimiter);
}
Console.WriteLine();
}
}
internal class Foo
{
override public string ToString()
{
return "FooClass";
}
}
internal class Program
{
static void Main(string[] args)
{
var myIntList = new List<int> {1, 2, 3, 4, 5};
var myDoubleList = new List<double> {1.1, 2.2, 3.3, 4.4};
var myDoubleArray = new Double[] {12.3, 12.4, 12.5, 12.6};
var myFooList = new List<Foo> {new Foo(), new Foo(), new Foo()};
// Using the standard delimiter /t
myIntList.WriteToConsole();
myDoubleList.WriteToConsole();
myDoubleArray.WriteToConsole();
myFooList.WriteToConsole();
// Using our own delimiter ~
myIntList.WriteToConsole("~");
Console.Read();
}
}
}
=======================================================
You might think that this should be the end of the answer. However there is a further piece of generalisation that can be done. It's not clear from fatcat's question if he is always writing to the console. Perhaps something else is to be done in the foreach. In that case Jason Bunting's answer is going to give that generality. Here is his answer again:
list.ForEach(i => Console.Write("{0}\t", i));
That is unless we make one more refinement to our extension methods and add FastForEach as below:
public static void FastForEach<T>(this IList<T> collection, Action<T> actionToPerform)
{
int count = collection.Count();
for (int i = 0; i < count; ++i)
{
actionToPerform(collection[i]);
}
Console.WriteLine();
}
This allows us to execute any arbitrary code against every element in the collection using the fastest possible iteration method.
We can even change the WriteToConsole function to use FastForEach
public static void WriteToConsole<T>(this IList<T> collection, string delimiter)
{
collection.FastForEach(item => Console.Write("{0}{1}", item.ToString(), delimiter));
}
So now the entire source code, including an example usage of FastForEach is:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleWritelineTest
{
public static class Extensions
{
public static void WriteToConsole<T>(this IList<T> collection)
{
WriteToConsole<T>(collection, "\t");
}
public static void WriteToConsole<T>(this IList<T> collection, string delimiter)
{
collection.FastForEach(item => Console.Write("{0}{1}", item.ToString(), delimiter));
}
public static void FastForEach<T>(this IList<T> collection, Action<T> actionToPerform)
{
int count = collection.Count();
for (int i = 0; i < count; ++i)
{
actionToPerform(collection[i]);
}
Console.WriteLine();
}
}
internal class Foo
{
override public string ToString()
{
return "FooClass";
}
}
internal class Program
{
static void Main(string[] args)
{
var myIntList = new List<int> {1, 2, 3, 4, 5};
var myDoubleList = new List<double> {1.1, 2.2, 3.3, 4.4};
var myDoubleArray = new Double[] {12.3, 12.4, 12.5, 12.6};
var myFooList = new List<Foo> {new Foo(), new Foo(), new Foo()};
// Using the standard delimiter /t
myIntList.WriteToConsole();
myDoubleList.WriteToConsole();
myDoubleArray.WriteToConsole();
myFooList.WriteToConsole();
// Using our own delimiter ~
myIntList.WriteToConsole("~");
// What if we want to write them to separate lines?
myIntList.FastForEach(item => Console.WriteLine(item.ToString()));
Console.Read();
}
}
}
List<int> list = new List<int> { 1, 3, 5 };
list.ForEach(x => Console.WriteLine(x));
Edit: Dammit! took too long to open visual studio to test it.
List<int> a = new List<int>() { 1, 2, 3, 4, 5 };
a.ForEach(p => Console.WriteLine(p));
edit: ahhh he beat me to it.
list.ForEach(x=>Console.WriteLine(x));
Also you can do join:
var qwe = new List<int> {5, 2, 3, 8};
Console.WriteLine(string.Join("\t", qwe));
public static void WriteLine(this List<int> theList)
{
foreach (int i in list)
{
Console.Write("{0}\t", t.ToString());
}
Console.WriteLine();
}
Then, later...
list.WriteLine();