나는 다음이있다
data.AppendFormat("{0},",dataToAppend);
이것의 문제는 내가 루프에서 사용하고 있고 시험용 쉼표가 있다는 것입니다. 후행 쉼표를 제거하는 가장 좋은 방법은 무엇입니까?
데이터를 문자열 하위 문자열로 변경해야합니까?
나는 다음이있다
data.AppendFormat("{0},",dataToAppend);
이것의 문제는 내가 루프에서 사용하고 있고 시험용 쉼표가 있다는 것입니다. 후행 쉼표를 제거하는 가장 좋은 방법은 무엇입니까?
데이터를 문자열 하위 문자열로 변경해야합니까?
답변:
가장 간단하고 효율적인 방법 은 다음 명령을 수행하는 것 입니다.
data.Length--;
이렇게하면 포인터 (예 : 마지막 인덱스)를 한 문자 뒤로 이동하지만 개체의 변경 가능성은 변경하지 않습니다. 사실, a를 지우는 StringBuilder
것도 가장 좋은 방법입니다 Length
(그러나 실제로 Clear()
구현이보기 때문에 명확성을 위해 메서드를 사용하십시오 ).
data.Length = 0;
다시 말하지만 할당 테이블을 변경하지 않기 때문입니다. 이 바이트를 더 이상 인식하고 싶지 않다고 생각하십시오. 이제를 호출 ToString()
할 때도을 (를) 지나는 것을 인식 Length
하지 못합니다. 그것은 당신이 제공하는 것보다 더 많은 공간을 할당하는 변경 가능한 객체이며, 단순히 이런 방식으로 구축되었습니다.
data.Length = 0;
: 정확히하는 StringBuilder.Clear
일이므로 StringBuilder.Clear
의도의 명확성을 위해 사용 하는 것이 좋습니다 .
Clear()
했지만 재미있는 일입니다. 이것이 방법 의 첫 번째 줄 입니다 Clear()
. 그러나 인터페이스가 실제로 return this;
. 이제 그게 나를 죽이는 것입니다. Length = 0
변경 사항을 이미 가지고있는 참조로 설정하는 이유는 무엇입니까?
Append
자신도 반환합니다.
그냥 사용
string.Join(",", yourCollection)
이렇게하면 StringBuilder
및 루프 가 필요하지 않습니다 .
비동기 케이스에 대한 긴 추가. 2019 년에는 데이터가 비동기 적으로 들어오는 경우가 드물지 않습니다.
데이터가 비동기 수집에있는 경우에는이 없습니다 string.Join
과부하 복용 IAsyncEnumerable<T>
. 그러나 다음에서 코드를string.Join
해킹 하여 수동으로 생성하는 것은 쉽습니다 .
public static class StringEx
{
public static async Task<string> JoinAsync<T>(string separator, IAsyncEnumerable<T> seq)
{
if (seq == null)
throw new ArgumentNullException(nameof(seq));
await using (var en = seq.GetAsyncEnumerator())
{
if (!await en.MoveNextAsync())
return string.Empty;
string firstString = en.Current?.ToString();
if (!await en.MoveNextAsync())
return firstString ?? string.Empty;
// Null separator and values are handled by the StringBuilder
var sb = new StringBuilder(256);
sb.Append(firstString);
do
{
var currentValue = en.Current;
sb.Append(separator);
if (currentValue != null)
sb.Append(currentValue);
}
while (await en.MoveNextAsync());
return sb.ToString();
}
}
}
데이터가 비동기 적으로오고 있지만 인터페이스 IAsyncEnumerable<T>
가 지원되지 않는 경우 (주석에서 언급 한 것처럼 SqlDataReader
) 데이터를 다음으로 래핑하는 것이 상대적으로 쉽습니다 IAsyncEnumerable<T>
.
async IAsyncEnumerable<(object first, object second, object product)> ExtractData(
SqlDataReader reader)
{
while (await reader.ReadAsync())
yield return (reader[0], reader[1], reader[2]);
}
그리고 그것을 사용하십시오 :
Task<string> Stringify(SqlDataReader reader) =>
StringEx.JoinAsync(
", ",
ExtractData(reader).Select(x => $"{x.first} * {x.second} = {x.product}"));
사용하려면 Select
, 당신은 nuget 패키지를 사용해야합니다 System.Interactive.Async
. 여기 에서 컴파일 가능한 예제를 찾을 수 있습니다.
string.Join(",", yourCollection)
여전히 ,
끝에 있습니다. 따라서 위의 즉, string.Join(",", yourCollection)
비효율적이며 스스로 제거하지 않습니다.
루프 후에 다음을 사용하십시오.
.TrimEnd(',')
또는 단순히 변경
string commaSeparatedList = input.Aggregate((a, x) => a + ", " + x)
string.Join(",", input)
나는 stringbuilder의 길이를 조작하는 것을 선호합니다.
data.Length = data.Length - 1;
data.Length--
또는 --data.Length
?
--
또는 ++
당신은 사용할 수 data.Length -= 1
있지만, 또는이 답변도 작동합니다.
루프 알고리즘을 변경하는 것이 좋습니다.
예, 루프가 완료되면 문자열로 변환하십시오.
String str = data.ToString().TrimEnd(',');
두 가지 옵션이 있습니다. 첫 번째는 매우 사용하기 쉬운 Remove
방법으로 매우 효과적입니다. 두 번째 방법은 ToString
시작 색인 및 끝 색인과 함께 사용하는 것 입니다 ( MSDN 문서 ).
가장 간단한 방법은 Join () 메서드를 사용하는 것입니다.
public static void Trail()
{
var list = new List<string> { "lala", "lulu", "lele" };
var data = string.Join(",", list);
}
StringBuilder가 정말로 필요한 경우 루프 뒤의 끝 쉼표를 잘라냅니다.
data.ToString().TrimEnd(',');
data.ToString().TrimEnd(',');
비효율적
이 스레드에 대한 대부분의 답변은 AppendLine
아래와 같이 사용하면 작동하지 않습니다 .
var builder = new StringBuilder();
builder.AppendLine("One,");
builder.Length--; // Won't work
Console.Write(builder.ToString());
builder = new StringBuilder();
builder.AppendLine("One,");
builder.Length += -1; // Won't work
Console.Write(builder.ToString());
builder = new StringBuilder();
builder.AppendLine("One,");
Console.Write(builder.TrimEnd(',')); // Won't work
왜??? @ (& ** (& @ !!
문제는 간단하지만 알아내는 데 시간이 좀 걸렸습니다 . 끝에 2 개의 보이지 않는 문자가 더 CR
있고 LF
(캐리지 리턴 및 줄 바꿈) 이 있기 때문 입니다. 따라서 마지막 3 개의 문자를 제거해야합니다.
var builder = new StringBuilder();
builder.AppendLine("One,");
builder.Length -= 3; // This will work
Console.WriteLine(builder.ToString());
결론적으로
사용 Length--
또는 Length -= 1
당신이 마지막으로 호출 방법이 있다면 Append
. Length =- 3
마지막으로 호출 한 메서드 인 경우 사용 합니다 AppendLine
.
string.Join(",", yourCollection)
? 편집 : 답변으로 추가되었습니다.