2009-06-14 4 views
6

클래스 String에는 매우 유용한 메서드 인 String.Join(string, string[])이 들어 있습니다.IEnumerable에 대한 String.Join (string, string [])의 유사어 <T>

주어진 기호로 배열의 각 요소를 분리하여 배열에서 문자열을 생성합니다. 하지만 일반 - 그것은 마지막 요소 뒤에 구분 기호를 추가하지 않습니다! 나는 "<br />"또는 Environment.NewLine으로 분리하기 위해 ASP.NET 코딩에 사용합니다.

그래서 각 행 다음에 빈 행을 추가하려면 asp:Table에 입력하십시오. 동일한 기능으로 어떤 방법을 사용합니까? ?

+0

그냥 새 TableRow :


덧붙여, String.Join의 또 다른 가능한 아날로그은 Intercalate 기능은 내가 찾던 사실 인인가? – spender

+0

'IEnumerable '은 문자열을 취하는 join-method와 어떻게 작동합니까? 즉, 실제로 기존 메서드를 어떻게 호출하고 있습니까? 나는 당신이 여기서 무엇을 찾고 있는지 정확히 이해하지 못합니다. –

+1

나는 현재'String.Join'을 전혀 호출하지 않습니다. 동일한 기능을 찾고 있습니다 - 배열 요소 사이에 구분 기호를 삽입하십시오 – abatishchev

답변

8

내가 확장 방법을 썼습니다 :

public static IEnumerable<T> 
     Join<T>(this IEnumerable<T> src, Func<T> separatorFactory) 
    { 
     var srcArr = src.ToArray(); 
     for (int i = 0; i < srcArr.Length; i++) 
     { 
      yield return srcArr[i]; 
      if(i<srcArr.Length-1) 
      { 
       yield return separatorFactory(); 
      } 
     } 
    } 

당신은 그것을 사용할 수 있습니다 여기에 테이블을,하지만 당신은 무엇을 조정할 수 이상 확장 방법

tableRowList.Join(()=>new TableRow()) 
+2

내가이 질문을 크게 오해하지 않으면 위의 코드는 의미가 없습니다. 마지막 항목의 분리 기호 *를 반환합니다. ?? 뭐? –

+0

미스터. @abatischev가 내 코드를 변경했습니다. 흠. rev 1을 확인하십시오. – spender

+0

방금 ​​들여 쓰기를 조금 새로 디자인했는데 방해가되면 미안하지만 필요하다고 생각하면 의심없이 롤백합니다. – abatishchev

0

내장 된 방법이 없으므로 직접 롤백해야합니다.

+1

"IEnumerable의 어떤 메소드 ...?" 도움이되지는 않지만 정답입니다. 확실히 downvote 가치가 없습니다. – spender

1

내 필요에 맞는 방법을 찾을 수 없다면, 내 자신을 만들 것입니다. 확장 메소드는 이런 식으로 확장 할 수 있기 때문에 매우 좋습니다. ASP에 대해 잘 몰라 : P

public static class TableRowExtensions 
{ 
    public string JoinRows(this IEnumerable<TableRow> rows, string separator) 
    { 
     // do what you gotta do 
    } 
} 
0

이런 종류의 일을 자주 수행하려는 경우 자신의 확장 방법을 구축 할 가치가 있습니다. 아래 구현은 string.Join(", ", arrayOfStrings)에 해당하는 작업을 수행 할 수 있습니다. 여기서 arrayOfStrings는 IEnumerable<T>이 될 수 있으며 구분 기호는 모든 객체가 될 수 있습니다.

  1. 그것은 LINQ의 맥락에서 매우 읽을 수있다 : I는 이것에 대해 좋아

    var names = new [] { "Fred", "Barney", "Wilma", "Betty" }; 
    var list = names 
        .Where(n => n.Contains("e")) 
        .Join(", "); 
    

    두 가지 : 그것은 당신이 이런 일을 수행 할 수 있습니다.

  2. StringBuilder를 사용하고 열거 형을 두 번 평가하지 않기 때문에 상당히 효율적입니다. 이 확장 방법을 사용할 수 있습니다 .NET 3.5에서
public static string Join<TItem,TSep>(
    this IEnumerable<TItem> enuml, 
    TSep     separator) 
{ 
    if (null == enuml) return string.Empty; 

    var sb = new StringBuilder(); 

    using (var enumr = enuml.GetEnumerator()) 
    { 
     if (null != enumr && enumr.MoveNext()) 
     { 
      sb.Append(enumr.Current); 
      while (enumr.MoveNext()) 
      { 
       sb.Append(separator).Append(enumr.Current); 
      } 
     } 
    } 

    return sb.ToString(); 
} 
+0

그러나 컬렉션을 두 번 평가합니다. 이것이 데이터베이스 쿼리 인 경우에는 효율적이지 않습니다. 또한 여기에 제네릭 형식을 잃어 버리고 문자열에서만 작동하게하는 것이 더 자연 스럽습니다. –

+0

@Lasse 예, 그렇습니다. 나는 메모리 내에서만 추측하고 있었다. 이제 열거 형을 한 번만 평가하도록 리팩터링했습니다. –

+0

왜 foreach 문을 사용하지 않습니까? 지금 당장 당신은 자원 누출 가능성이 있습니다. 적어도 .GetEnumerator()와 함께'using' 문을 사용해야합니다. –

5

:

public static string Join<TItem>(this IEnumerable<TItem> enumerable, string separator) 
{ 
    return string.Join(separator, enumerable.Select(x => x.ToString()).ToArray()); 
} 

또는 .NET 4

public static string Join<TItem>(this IEnumerable<TItem> enumerable, string separator) 
{ 
    return string.Join(separator, enumerable); 
} 

의를하지만 문제는 포함 각 요소 후 분리를 원했다 이 3.5 버전이 작동하는 마지막 버전 : -

public static string AddDelimiterAfter<TItem>(this IEnumerable<TItem> enumerable, string delimiter) 
{ 
    return string.Join("", enumerable.Select(x => x.ToString() + separator).ToArray()); 
} 

.Aggregate를 사용하여 확장 방법이없는 을 사용할 수도 있습니다.

8

String.Join의 Linq에 상당하는 예를 들어 Aggregate

이다 TableRows의 IE가 주어진다면

IEnumerable<string> strings; 
string joinedString = strings.Aggregate((total,next) => total + ", " + next); 

코드는 유사 할 것이다.

+3

경고 : 이것은 String.Join과 기능적으로 동일 할 수도 있지만 구현이 다르다. 'String.Join'은'StringBuilder'를 사용하여 일시적인'String' 인스턴스 전체를 할당하는 것을 피하기에 충분히 똑똑합니다. 반면 위의 코드는 그렇지 않습니다. –

+0

@KentBoogaart 원래 질문은 행동을 복제하는 일반적인 방법에 관한 것이었기 때문에 특별히 중요하지는 않습니다. 'string.Join'은 'intersperse'행동을 갖는 함수의 예일뿐입니다. – Pharap

1

찾고있는 것은 Intersperse입니다. 이러한 함수의 LINQ 구현에 대해서는 this question을 참조하십시오. 삽입 된 값에 대한

public static IEnumerable<T> Intercalate<T>(this IEnumerable<IEnumerable<T>> source, 
              IEnumerable<T> separator) { 
    if (source == null) throw new ArgumentNullException("source"); 
    if (separator == null) throw new ArgumentNullException("separator"); 
    return source.Intersperse(separator) 
     .Aggregate(Enumerable.Empty<T>(), Enumerable.Concat); 
} 
관련 문제