質問
列挙の質問をする.NETの方法(または標準の拡張メソッドのいくつかの並べ替え)があるのでしょうか?
たとえば、現在のアイテムが列挙内の最初または最後の項目である
string s = "";
foreach (var person in PeopleListEnumerator) {
if (PeopleListEnumerator.IsFirstItem) s += "[";
s += person.ToString();
if (!PeopleListEnumerator.IsLastItem) s += ",";
else s += "]";
}
解決
楽しいだけのために、先行評価を必要とし、(列挙子を除く)単一のローカル変数を持っていない一般的な問題の解決のために:
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);
}
}
}
}
テスト
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);
}
}
}
他のヒント
あなたのコレクションがリストである場合は、あなたが行うことができます:
string s = "[" + String.Join(",", PeopleList.ToArray()) + "]";
私が知らないことを。あなたはしかし、そのような拡張メソッドを自分で書いてみることができます。それとも別の場所で最後の/最初の項目を追跡します。
エリックリペットはブログ記事を持っていました問題のようなものについて、最近、より正確にあなたが実際に欲しいものを反映するように、あなたの問題の説明を変更する方法についていくつかの考えと一緒ます。
あなたはhref="http://msdn.microsoft.com/en-us/library/57a79xd0.aspx" rel="nofollow noreferrer"> String.Join の
String.Join(
",",
(from p in PeopleListEnumerator
select p.ToString()).ToArray()
)
IEnumerableインターフェイスは、任意の順序であること戻りアイテムを定義したり、期待していません。だから、「第一」の概念が常に適用されません。
しかし、この特定のパターンのために、これは私が何をすべきかです。
StringBuilder result = new StringBuilder();
result.Append( '[' );
foreach( var person in PeopleListEnumerator )
{
if( result.Length > 1 )
result.Append( ',' );
result.Append( person.ToString() );
}
result.Append( ']' );
LINQを使用して、あなたが行うことができます:
string s =
string.Format("[{0}]", string.Join(",",PeopleListEnumerator.Select(p => p.ToString()).ToArray()));
私は、例えば、自分が定義し、「ブール最初の」ローカル変数を使用して検索します
string s = "[";
bool first = true;
foreach (var person in PeopleListEnumerator) {
if (first)
first = false;
else
s += ",";
s += person.ToString();
}
s += "]";
このコードは、密接にあなたが本当に達成したいものと一致します:
StringBuilder s = new StringBuilder("[");
string delimiter = "";
foreach (var person in PeopleListEnumerator) {
s.Append(delimiter).Append(person.ToString());
delimiter = ",";
}
return s.Append("]").ToString();
私はこの猫を肌たい方法でしょう(はい、多くの方法ということがあります)
StringBuilder sb = new StringBuilder();
foreach (var person in PeopleListEnumerator )
{
sb.AppendFormat(",{0}", person.ToString());
}
string s = "[" + sb.ToString().Substring(1) + "]";
この情報がお役に立てば幸い...
.NET列挙型では、値による場合を除いて、順序の概念はありません。あなたが最初と最後の列挙は、私がお勧めしたい場合は、明示的にこれらの最初と最後の値が何であるかを定義します。以下の列挙はその一例です。
public enum PlayerType : byte
{
Starter = byte.MinValue,
RegularPlayer = 1,
BenchWarmer = 2,
Closer = byte.MaxValue
}
あなたは、次のようなものを表現することができます:
List<byte> values = new List<byte>((byte[])Enum.GetValues(typeof(PlayerType)));
PlayerType starter = (PlayerType)values.Min();
PlayerType closer = (PlayerType)values.Max();