.NET 열거 첫 번째와 마지막
-
20-08-2019 - |
문제
.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()) + "]";
내가 아는 한에서는 아니다. 그래도 이러한 확장 방법을 직접 작성해보십시오. 또는 다른 곳에서 첫 번째/마지막 항목을 추적하십시오.
Eric Lippert는 a 블로그 게시물 최근에 이러한 종류의 문제에 대해 최근에 문제 설명을 수정하는 방법에 대한 생각과 함께 실제로 원하는 것을보다 정확하게 반영합니다.
당신은 아마도 a를 사용하는 것이 좋습니다 String.join 이 경우 일부 LINQ와 함께 :
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()));
예를 들어 "Bool First"로컬 변수를 정의하고 사용합니다.
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();