.net listing the first and last

Is there a way in .NET (or some standard extension methods) to ask enumeration questions?

For example, the current item is the first or last item in the enumeration:

string s = ""; foreach (var person in PeopleListEnumerator) { if (PeopleListEnumerator.IsFirstItem) s += "["; s += person.ToString(); if (!PeopleListEnumerator.IsLastItem) s += ","; else s += "]"; } 
+4
source share
10 answers

Just for fun, a solution to a general problem that does not require a high score and has one local variable (except for the enumerator):

 static class TaggedEnumerableExtensions { public class TaggedItem<T> { public TaggedItem(T value, bool isFirst, bool isLast) { IsFirst = isFirst; IsLast = isLast; Value = value; } public T Value { get; private set; } public bool IsFirst { get; private set; } public bool IsLast { get; private set; } } public static IEnumerable<TaggedItem<T>> ToTaggedEnumerable<T>(this IEnumerable<T> e) { using (var enumerator = e.GetEnumerator()) { if (!enumerator.MoveNext()) yield break; var current = enumerator.Current; if (!enumerator.MoveNext()) { yield return new TaggedItem<T>(current, true, true); yield break; } else { yield return new TaggedItem<T>(current, true, false); } for (;;) { current = enumerator.Current; if (!enumerator.MoveNext()) { yield return new TaggedItem<T>(current, false, true); yield break; } yield return new TaggedItem<T>(current, false, false); } } } } 

Test:

 class Program { static void Main(string[] args) { foreach (var item in Enumerable.Range(0, 10).ToTaggedEnumerable()) { Console.WriteLine("{0} {1} {2}", item.IsFirst, item.IsLast, item.Value); } } } 
+8
source

If your collection is a list, you can do:

 string s = "[" + String.Join(",", PeopleList.ToArray()) + "]"; 
+3
source

Not that I knew. However, you can try writing such extension methods. Or track the first / last item elsewhere.

Eric Lippert has recently reported this issue, along with some thoughts on how to change the description of the problem to more accurately reflect what you really want.

You should probably use String.Join with some LINQ in this case:

 String.Join( ",", (from p in PeopleListEnumerator select p.ToString()).ToArray() ) 
+2
source

The IEnumerable interface does not determine or expect that the elements it returns will be in any given order. Thus, the concept of "First" is not always applied.

However, for this particular template, this is what I do

 StringBuilder result = new StringBuilder(); result.Append( '[' ); foreach( var person in PeopleListEnumerator ) { if( result.Length > 1 ) result.Append( ',' ); result.Append( person.ToString() ); } result.Append( ']' ); 
+1
source

Using LINQ, you can:

 string s = string.Format("[{0}]", string.Join(",",PeopleListEnumerator.Select(p => p.ToString()).ToArray())); 
+1
source

John Skeet wrote Smart Enumerations to provide this functionality, and they are part of the MiscUtils library .

However, your specific example is best resolved by the String.Join () method, as many others have pointed out. Writing a common extension to string Join(this IEnumerable<T>,string) not difficult, and then it can be used in any situation without resorting to annoying temporary arrays.

+1
source

I define and use the local variable "bool first", for example:

 string s = "["; bool first = true; foreach (var person in PeopleListEnumerator) { if (first) first = false; else s += ","; s += person.ToString(); } s += "]"; 
0
source

This code exactly matches what you really want to execute:

 StringBuilder s = new StringBuilder("["); string delimiter = ""; foreach (var person in PeopleListEnumerator) { s.Append(delimiter).Append(person.ToString()); delimiter = ","; } return s.Append("]").ToString(); 
0
source

The way I will cheat this cat (yes, there are many ways):

 StringBuilder sb = new StringBuilder(); foreach (var person in PeopleListEnumerator ) { sb.AppendFormat(",{0}", person.ToString()); } string s = "[" + sb.ToString().Substring(1) + "]"; 

Hope this helps ...

0
source

In .NET enumerations, there is no concept of order other than meaning. If you want to get the first and last enumeration, I would suggest explicitly defining what these first and last values ​​are. Listed below:

 public enum PlayerType : byte { Starter = byte.MinValue, RegularPlayer = 1, BenchWarmer = 2, Closer = byte.MaxValue } 

Then you can express something similar to the following:

 List<byte> values = new List<byte>((byte[])Enum.GetValues(typeof(PlayerType))); PlayerType starter = (PlayerType)values.Min(); PlayerType closer = (PlayerType)values.Max(); 
-2
source

All Articles