স্ট্রিংবিল্ডার দিয়ে নির্মিত স্ট্রিং থেকে শেষ অক্ষরটি সরিয়ে ফেলার সেরা উপায়


92

আমি নিম্নলিখিত আছে

data.AppendFormat("{0},",dataToAppend);

এর সাথে সমস্যা হ'ল আমি এটিকে একটি লুপে ব্যবহার করছি এবং সেখানে একটি ট্রায়ালিং কমা হবে। পেছনের কমা অপসারণের সেরা উপায় কী?

আমাকে কি স্ট্রিংয়ের স্ট্রিংয়ে ডেটা পরিবর্তন করতে হবে?


10
string.Join(",", yourCollection)? সম্পাদনা: উত্তর হিসাবে যুক্ত।
ভ্লাদ


@ ক্রিস: এইভাবে আপনার কোনও স্ট্রিংবিল্ডার লাগবে না।
ভ্লাদ

সম্ভবত আপনি পরে মুছে ফেলার পরিবর্তে কমা যোগ করা এড়াতে পারেন। দেখুন: স্ট্যাকওভারফ্লো.com/ প্রশ্নগুলি / ৫৮১৪৪৪/২ (জন স্কিটির উত্তর)
পাওলো ফালেবেলা

@ ভ্ল্যাড হ্যাঁ দুঃখিত, আমি এটি ভুল লিখেছি; আমি ভেবেছিলাম আপনি এটিকে চূড়ান্তভাবে নির্মিত স্ট্রিংটি পরিবর্তনের পরামর্শ হিসাবে প্রস্তাব করছেন, তার লুপের পুরোপুরি প্রতিস্থাপন হিসাবে নয়। (আমি ভেবেছিলাম সময় মতো আমার মন্তব্য মুছে ফেলেছি, অনুমান করবেন না!)
ক্রিস সিনক্লেয়ার

উত্তর:


224

সবচেয়ে সহজ এবং সর্বাধিক দক্ষ উপায় হ'ল এই আদেশটি পালন করা:

data.Length--;

এটি করার মাধ্যমে আপনি পয়েন্টারটি (অর্থাত্ শেষ সূচক) একটি অক্ষর পিছনে সরিয়ে ফেলেন তবে আপনি বস্তুর পরিবর্তন করতে পারবেন না। প্রকৃতপক্ষে, একটি সাফ করার পাশাপাশি ভালভাবে StringBuilderসম্পন্ন করা Lengthহয় (তবে প্রকৃতপক্ষে Clear()স্পষ্টতার জন্য পদ্ধতিটি ব্যবহার করুন কারণ এর বাস্তবায়ন দেখতে এটিই তাই):

data.Length = 0;

আবার, কারণ এটি বরাদ্দ সারণী পরিবর্তন করে না। এটিকে বলার মতো ভাবুন, আমি এই বাইটগুলি আর স্বীকৃতি দিতে চাই না। এখন, কল করার পরেও ToString()এটি এর অতীতের কোনও কিছুই চিনবে না Length, ভাল, এটি পারে না। এটি একটি পরিবর্তনীয় অবজেক্ট যা আপনি যা সরবরাহ করেন তার চেয়ে বেশি জায়গা বরাদ্দ করে, এটি কেবল এইভাবে নির্মিত।


4
পুনরায় data.Length = 0;: ঠিক StringBuilder.Clearএটিই তাই, তাই StringBuilder.Clearউদ্দেশ্যটির স্পষ্টতার জন্য এটি ব্যবহার করা ভাল ।
এরেন এরসনেমেজ

@ ইরেনআর্সনেমেজ, মোটামুটি যথেষ্ট বন্ধু, আমার আরও স্পষ্ট করে বলা উচিত যা যা Clear()করে তা কিন্তু মজার বিষয়। এটা প্রথম লাইন এর Clear()পদ্ধতি। তবে, আপনি কি ইন্টারফেসটি আসলে জানতেন return this;? এখন সেটাই আমাকে মেরে ফেলেছে। Length = 0আপনার ইতিমধ্যে রেফারেন্স পরিবর্তনগুলি সেট করা, কেন নিজেকে ফেরাবেন?
মাইক পেরেনউড

12
আমি মনে করি এটি "সাবলীল" উপায়ে ব্যবহার করতে সক্ষম হওয়ার জন্য। Appendপাশাপাশি ফিরে আসে।
এরেন এরনেসমেজ

43

শুধু ব্যবহার

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আপনাকে নুগেট প্যাকেজটি ব্যবহার করতে হবে System.Interactive.Asyncএখানে আপনি একটি সংকলনযোগ্য উদাহরণ খুঁজে পেতে পারেন।


12
সর্বোত্তম উত্তরটি সেই সমস্যাটিকে সম্বোধন করে না, তবে এটিই এটি প্রতিরোধ করে।
লাস্টটিবুনাল

4
@ শেবিজকিট: অবশ্যই! পুরো প্রশ্নটি উপায়, উপায় # নিয়েই।
ভ্লাদ

4
@ ভ্ল্যাড আমি পেয়েছি, কেবল কাঁচা পরীক্ষার মতো সাধারণ পরীক্ষা করছি বলে তারা ডাবল চেকিং করছে এবং সেগুলিও তেমন তৈরি হয়নি। string.Join(",", yourCollection)এখনও একটি ,শেষে আছে। সুতরাং উপরোক্ত অর্থ string.Join(",", yourCollection)অকার্যকর এবং এটি নিজে থেকে এটি সরান না।
Seabizkit

4
@ শেবিজকিট: খুব অদ্ভুত! আপনি একটি উদাহরণ পোস্ট করতে পারেন? আমার কোডে এটি নিখুঁতভাবে কাজ করে: ideone.com/aj8PWR
ভ্লাদ

4
স্ট্রিং বিল্ডার তৈরি করতে লুপ ব্যবহার করার বছর এবং তারপরে কমাটি মুছে ফেলতে পেরেছি এবং আমি এটি ব্যবহার করতে পারতাম। টিপ জন্য ধন্যবাদ!
কেভারম্যান

11

লুপের পরে নিম্নলিখিতটি ব্যবহার করুন।

.TrimEnd(',')

বা সহজভাবে পরিবর্তন

string commaSeparatedList = input.Aggregate((a, x) => a + ", " + x)

4
তিনি স্ট্রিংবিল্ডার নয় স্ট্রিং ব্যবহার করছেন। তবুও এটি বেশ অকার্যকর: প্রথমে স্ট্রিংয়ে রূপান্তরকরণ এর পরে ছাঁটাই।
পাইওটার স্টাপ

বাstring.Join(",", input)
Tvde1

11

এই সম্পর্কে ..

string str = "The quick brown fox jumps over the lazy dog,";
StringBuilder sb = new StringBuilder(str);
sb.Remove(str.Length - 1, 1);

7

আমি স্ট্রিংবিল্ডারের দৈর্ঘ্যের কারসাজি করতে পছন্দ করি

data.Length = data.Length - 1;

4
কেন সহজ data.Length--বা না --data.Length?
7:40

আমি সাধারণত ডেটা ব্যবহার করি en দৈর্ঘ্য-- তবে একটি ক্ষেত্রে আমি যে চরিত্রটি সরাতে চেয়েছিলাম তার পরে ফাঁকা মান হওয়ায় আমাকে 2 টি অক্ষর ফিরে যেতে হয়েছিল। ট্রিম সে ক্ষেত্রে এতটা ডেটাও কাজ করেনি। দৈর্ঘ্য = ডেটা en কাজ করছে.
কেভারম্যান

ট্রিম একটি স্ট্রিংয়ের একটি নতুন উদাহরণ দেয়, এটি স্ট্রিংবিল্ডার অবজেক্টের বিষয়বস্তুগুলি পরিবর্তন করে না
bastos.sergio

@ গনকোডিং ভিজ্যুয়াল বেসিক .NET সমর্থন করে না --বা ++ আপনি data.Length -= 1যদিও ব্যবহার করতে পারেন , বা এই উত্তরটিও কার্যকর হবে।
জেসন এস

3

আমি সুপারিশ করছি, আপনি আপনার লুপ অ্যালগরিদম পরিবর্তন করুন:

  • আইটেমের পরে নয়, আগে কমা যোগ করুন
  • বুলিয়ান ভেরিয়েবল ব্যবহার করুন, যা মিথ্যা দিয়ে শুরু হয়, প্রথম কমাটি দমন করে না
  • এই বুলিয়ান ভেরিয়েবলটি এটির পরীক্ষার পরে সত্যে সেট করুন

4
এটি সম্ভবত সমস্ত পরামর্শের মধ্যে সবচেয়ে কম দক্ষ (এবং আরও কোডের প্রয়োজন)।
কোডিং হয়ে গেছে

4
@Vlad উত্তর তাকান
Noctis

3

string.Joinআইটেমের সংগ্রহকে কমা বিস্মৃত স্ট্রিংয়ে রূপান্তর করতে আপনার পদ্ধতিটি ব্যবহার করা উচিত । এটি নিশ্চিত করবে যে কোনও নেতৃস্থানীয় বা অনুসরণীয় কমা নেই, পাশাপাশি স্ট্রিংটি দক্ষতার সাথে নির্মান করা হয়েছে (অপ্রয়োজনীয় মধ্যবর্তী স্ট্রিং ছাড়াই)।


2

হ্যাঁ, লুপটি শেষ হয়ে গেলে এটি একটি স্ট্রিংয়ে রূপান্তর করুন:

String str = data.ToString().TrimEnd(',');

4
এটি বেশ অকার্যকর: প্রথমে স্ট্রিংয়ে রূপান্তর তারপর ট্রিমিং।
পাইওটার স্টাপ

4
@ গারাথ যদি আপনি "অদক্ষ" বলতে চাইতেন তবে আমি দ্বিমত পোষণ করব না। কিন্তু এটা হবে কার্যকর হবে।
ডনবয়েটনট

2

আপনার কাছে দুটি বিকল্প রয়েছে। প্রথমটি খুব সহজে ব্যবহারের Removeপদ্ধতি এটি বেশ কার্যকর। দ্বিতীয় উপায়টি হল ToStringসূচক এবং শেষ সূচক ( এমএসডিএন ডকুমেন্টেশন ) এর সাথে ব্যবহার করা



1

সবচেয়ে সহজ উপায় হ'ল যোগদান () পদ্ধতিটি ব্যবহার করা:

public static void Trail()
{
    var list = new List<string> { "lala", "lulu", "lele" };
    var data = string.Join(",", list);
}

আপনার যদি সত্যিই স্ট্রিংবিল্ডারের প্রয়োজন হয় তবে লুপের পরে শেষ কমাটি ট্রিম করুন:

data.ToString().TrimEnd(',');

4
data.ToString().TrimEnd(',');অদক্ষ
bastos.sergio

4
এছাড়াও, আপনি স্ট্রিংবিল্ডার অবজেক্টটিকে স্ট্রিংয়ে রূপান্তর করতে নাও চাইবেন কারণ এতে "," দিয়ে শেষ হওয়া একাধিক লাইন থাকতে পারে
Fandango68

0

গোছা !!

আপনি 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

ফিডল মি

কেন ??? @ (& ** (& @ !!)

ইস্যুটি সহজ তবে এটি নির্ধারণ করতে আমাকে কিছুটা সময় নিয়েছে: কারণ শেষে আরও দুটি অদৃশ্য চরিত্র রয়েছে CRএবং LF(ক্যারিজ রিটার্ন এবং লাইন ফিড)। অতএব, আপনাকে শেষের তিনটি অক্ষর কেড়ে নিতে হবে:

var builder = new StringBuilder();
builder.AppendLine("One,");
builder.Length -= 3; // This will work
Console.WriteLine(builder.ToString());

উপসংহারে

আপনি Length--বা Length -= 1শেষ পদ্ধতিটি কল করেছিলেন তা ব্যবহার করুন AppendLength =- 3আপনি যদি শেষ পদ্ধতিটি কল করেন তবে ব্যবহার করুন AppendLine

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.