문제

구식을 쓰는 가장 효율적인 방법은 무엇입니까?

StringBuilder sb = new StringBuilder();
if (strings.Count > 0)
{
    foreach (string s in strings)
    {
        sb.Append(s + ", ");
    }
    sb.Remove(sb.Length - 2, 2);
}
return sb.ToString();

... LINQ에서?

도움이 되었습니까?

해결책

이 답변은 LINQ의 사용법을 보여줍니다 (Aggregate) 질문에 요청 된대로 일상적인 사용을위한 것이 아닙니다. 이것은 사용되지 않기 때문에 StringBuilder 매우 긴 시퀀스의 끔찍한 성능을 가질 것입니다. 정기적 인 코드 사용 String.Join 다른 쪽에서 볼 수 있듯이 대답

다음과 같은 집계 쿼리를 사용하십시오.

string[] words = { "one", "two", "three" };
var res = words.Aggregate(
   "", // start with empty string to handle empty list case.
   (current, next) => current + ", " + next);
Console.WriteLine(res);

이 출력 :

one, two, three

집계는 값을 모으고 스칼라 값을 반환하는 함수입니다. T-SQL의 예로는 Min, Max 및 Sum이 포함됩니다. VB와 C#은 모두 집계를 지원합니다. VB 및 C#은 모두 확장 방법으로 응집체를 지원합니다. 도트 계약을 사용하면 단순히 메소드를 호출합니다. ienumerable 물체.

집계 쿼리는 즉시 실행됩니다.

추가 정보 - MSDN : 집계 쿼리


정말로 사용하고 싶다면 Aggregate 변형 사용을 사용하십시오 StringBuilder 의견에 제안 CodemonKeyking 이것은 규칙과 거의 같은 코드입니다 String.Join 많은 객체에 대한 우수한 성능 포함 :

 var res = words.Aggregate(
     new StringBuilder(), 
     (current, next) => current.Append(current.Length == 0? "" : ", ").Append(next))
     .ToString();

다른 팁

return string.Join(", ", strings.ToArray());

.NET 4에는 새로운 것이 있습니다 초과 적재 ~을 위한 string.Join 그것은 받아들입니다 IEnumerable<string>. 코드는 다음과 같습니다.

return string.Join(", ", strings);

LINQ를 사용하는 이유는 무엇입니까?

string[] s = {"foo", "bar", "baz"};
Console.WriteLine(String.Join(", ", s));

그것은 완벽하게 작동하고 어떤 것을 받아들입니다 IEnumerable<string> 내가 기억하기로는. 필요 없음 Aggregate 여기에 훨씬 느린 것이 무엇이든.

집계 연장 방법을 살펴 보셨습니까?

var sa = (new[] { "yabba", "dabba", "doo" }).Aggregate((a,b) => a + "," + b);

내 코드의 실제 예 :

return selected.Select(query => query.Name).Aggregate((a, b) => a + ", " + b);

쿼리는 문자열 인 이름 속성이있는 객체이며 선택한 목록의 모든 쿼리의 이름을 쉼표로 분리하고 싶습니다.

당신이 사용할 수있는 StringBuilder 안에 Aggregate:

  List<string> strings = new List<string>() { "one", "two", "three" };

  StringBuilder sb = strings
    .Select(s => s)
    .Aggregate(new StringBuilder(), (ag, n) => ag.Append(n).Append(", "));

  if (sb.Length > 0) { sb.Remove(sb.Length - 2, 2); }

  Console.WriteLine(sb.ToString());

(그만큼 Select 더 많은 linq 일을 할 수 있다는 것을 보여주기 위해 거기에 있습니다.)

다음은 다른 답변과 해결 된 문제를 살펴본 후 해결 한 Join/LINQ 접근 방식입니다. 비슷한 질문에서 (즉, 골재 및 컨텍스트는 0 요소로 실패합니다).

string Result = String.Join(",", split.Select(s => s.Name));

또는 (if s 문자열이 아닙니다)

string Result = String.Join(",", split.Select(s => s.ToString()));

  • 단순한
  • 읽고 이해하기 쉽습니다
  • 일반 요소에 대해 작동합니다
  • 객체 또는 객체 속성을 사용할 수 있습니다
  • 0 길이 요소의 경우를 처리합니다
  • 추가 LINQ 필터링과 함께 사용할 수 있습니다
  • 잘 수행합니다 (적어도 내 경험에서)
  • 추가 객체의 (수동) 생성이 필요하지 않습니다 (예 : StringBuilder) 구현

그리고 물론 가입은 때때로 다른 접근법에 몰래 들어가는 성가신 최종 쉼표를 처리합니다.for, foreach), 이것이 내가 처음에 LINQ 솔루션을 찾고 있었던 이유입니다.

StringBuilder 대 3000 개 이상의 요소를 선택 및 집계 케이스에 대한 빠른 성능 데이터 :

단위 테스트 - 지속 시간 (초)
LINQ_STRINGBUILDER -0.0036644
linq_select.aggregate -1.8012535

    [TestMethod()]
    public void LINQ_StringBuilder()
    {
        IList<int> ints = new List<int>();
        for (int i = 0; i < 3000;i++ )
        {
            ints.Add(i);
        }
        StringBuilder idString = new StringBuilder();
        foreach (int id in ints)
        {
            idString.Append(id + ", ");
        }
    }
    [TestMethod()]
    public void LINQ_SELECT()
    {
        IList<int> ints = new List<int>();
        for (int i = 0; i < 3000; i++)
        {
            ints.Add(i);
        }
        string ids = ints.Select(query => query.ToString())
                         .Aggregate((a, b) => a + ", " + b);
    }

나는 항상 확장 방법을 사용합니다.

public static string JoinAsString<T>(this IEnumerable<T> input, string seperator)
{
    var ar = input.Select(i => i.ToString()).ToArray();
    return string.Join(seperator, ar);
}

에 의해 '슈퍼 쿨 LINQ 방식'당신은 LINQ가 확장 방법을 사용하여 기능적 프로그래밍을 훨씬 더 맛있게 만드는 방식에 대해 이야기하고있을 것입니다. 내 말은, 기능을 둥지 (하나는 다른 하나) 대신 시각적으로 선형적인 방식으로 (다른 한편으로는) 시각적으로 선형적인 방식으로 묶을 수 있도록하는 구문 설탕을 의미합니다. 예를 들어:

int totalEven = Enumerable.Sum(Enumerable.Where(myInts, i => i % 2 == 0));

다음과 같이 쓸 수 있습니다.

int totalEven = myInts.Where(i => i % 2 == 0).Sum();

두 번째 예제가 어떻게 읽기 쉬운 지 알 수 있습니다. 덜 들여 쓰기 문제 또는 리시 표현의 끝에 나타나는 파렌을 닫습니다.

다른 많은 대답은 String.Join 읽는 가장 빠르거나 단순하기 때문에가는 길입니다. 하지만 당신이 내 해석을하면 '슈퍼 쿨 LINQ 방식'그러면 대답은 사용하는 것입니다 String.Join 그러나 LINQ 스타일 확장 방법으로 래핑하여 기능을 시각적으로 즐거운 방식으로 체인 할 수 있습니다. 그래서 당신이 쓰고 싶다면 sa.Concatenate(", ") 당신은 다음과 같은 것을 만들어야합니다.

public static class EnumerableStringExtensions
{
   public static string Concatenate(this IEnumerable<string> strings, string separator)
   {
      return String.Join(separator, strings);
   }
}

이것은 직접 통화만큼 성능이있는 코드 (적어도 알고리즘 복잡성 측면에서)를 제공하며 경우에 따라 블록의 다른 코드가 사슬 된 기능 스타일을 사용하는 경우 (컨텍스트에 따라) 코드를 더 읽기 쉽게 만들 수 있습니다. .

이것에 대한 다양한 대안이 있습니다 이전 질문 - 정수 배열을 소스로 타겟팅했지만 일반화 된 답변을 받았습니다.

여기에서는 순수한 LINQ를 단일 표현식으로 사용합니다.

static string StringJoin(string sep, IEnumerable<string> strings) {
  return strings
    .Skip(1)
    .Aggregate(
       new StringBuilder().Append(strings.FirstOrDefault() ?? ""), 
       (sb, x) => sb.Append(sep).Append(x));
}

그리고 그 꽤 망할 빨리!

나는 약간의 속임수를 쓰고 이것에 대한 새로운 대답을 버릴 것입니다. 이에 대한 새로운 답변을 던질 것입니다. 이에 대한 새로운 대답을 던질 것입니다. 이에 대한 새로운 답변을 던질 것입니다.

그래서 당신은 이것을 한 줄에 할 수 있습니다 :

List<string> strings = new List<string>() { "one", "two", "three" };

string concat = strings        
    .Aggregate(new StringBuilder("\a"), 
                    (current, next) => current.Append(", ").Append(next))
    .ToString()
    .Replace("\a, ",string.Empty); 

편집하다: 빈 열거 가능한 먼저 확인하거나 추가 할 수 있습니다. .Replace("\a",string.Empty); 표현의 끝까지. 너무 똑똑해 지려고했을 것 같아요.

@a.friend의 답변은 약간 더 성능이있을 수 있습니다. 나는 제거에 비해 후드 아래에서 어떻게 교체하는지 잘 모르겠습니다. 유일한 다른 경고는 당신이 a로 끝나는 줄을 동의하고 싶다면 당신은 당신의 분리기를 잃을 것입니다 ... 나는 그럴 것 같지 않습니다. 그것이 당신이 가진 경우라면 다른 멋진 캐릭터 에서 고르다.

LINQ를 결합 할 수 있습니다 string.join() 상당히 효과적으로. 여기서 나는 문자열에서 항목을 제거하고 있습니다. 이 작업을 수행하는 더 좋은 방법이 있지만 여기에 다음과 같습니다.

filterset = String.Join(",",
                        filterset.Split(',')
                                 .Where(f => mycomplicatedMatch(f,paramToMatch))
                       );

여기에 많은 선택이 있습니다. LINQ와 StringBuilder를 사용할 수 있으므로 성능도 마찬가지입니다.

StringBuilder builder = new StringBuilder();
List<string> MyList = new List<string>() {"one","two","three"};

MyList.ForEach(w => builder.Append(builder.Length > 0 ? ", " + w : w));
return builder.ToString();

LINQ를 사용하여 IIS 로그 파일을 구문 분석 할 때 다음과 같은 빠르고 더러운 일을했는데, 2 백만 줄을 시도 할 때 메모리 오류가 발생했지만 1 백만 줄 (15 초) @ 1 백만 줄 (15 초)이 작동했습니다.

    static void Main(string[] args)
    {

        Debug.WriteLine(DateTime.Now.ToString() + " entering main");

        // USED THIS DOS COMMAND TO GET ALL THE DAILY FILES INTO A SINGLE FILE: copy *.log target.log 
        string[] lines = File.ReadAllLines(@"C:\Log File Analysis\12-8 E5.log");

        Debug.WriteLine(lines.Count().ToString());

        string[] a = lines.Where(x => !x.StartsWith("#Software:") &&
                                      !x.StartsWith("#Version:") &&
                                      !x.StartsWith("#Date:") &&
                                      !x.StartsWith("#Fields:") &&
                                      !x.Contains("_vti_") &&
                                      !x.Contains("/c$") &&
                                      !x.Contains("/favicon.ico") &&
                                      !x.Contains("/ - 80")
                                 ).ToArray();

        Debug.WriteLine(a.Count().ToString());

        string[] b = a
                    .Select(l => l.Split(' '))
                    .Select(words => string.Join(",", words))
                    .ToArray()
                    ;

        System.IO.File.WriteAllLines(@"C:\Log File Analysis\12-8 E5.csv", b);

        Debug.WriteLine(DateTime.Now.ToString() + " leaving main");

    }

내가 LINQ를 사용한 진짜 이유는 이전에 필요한 고유 한 ()에 대한 것이 었습니다.

string[] b = a
    .Select(l => l.Split(' '))
    .Where(l => l.Length > 11)
    .Select(words => string.Format("{0},{1}",
        words[6].ToUpper(), // virtual dir / service
        words[10]) // client ip
    ).Distinct().ToArray()
    ;

나는 얼마 전에 이것에 대해 블로그를 작성했다.

http://ondevelopment.blogspot.com/2009/02/string-concatenation-made-easy.html

블로그 게시물에서 ienumerable에서 작동하고 ConcateNate로 명명 된 확장 방법을 구현하는 방법을 설명하면 다음과 같은 내용을 쓸 수 있습니다.

var sequence = new string[] { "foo", "bar" };
string result = sequence.Concatenate();

또는 더 정교한 것들 :

var methodNames = typeof(IFoo).GetMethods().Select(x => x.Name);
string result = methodNames.Concatenate(", ");
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top