একটি সি # কেস সংবেদনশীল সমান অপারেটর নেই?


156

আমি জানি যে নিম্নলিখিতগুলি সংবেদনশীল:

if (StringA == StringB) {

তাহলে কি এমন কোনও অপারেটর রয়েছে যা সংবেদনশীল উপায়ে দুটি স্ট্রিংয়ের তুলনা করবে?



যদি কোনও শব্দ অভিধান <স্ট্রিং <<< জন্য কোনও সংবেদনশীল তুলনা খোঁজার জন্য এই প্রশ্নটি জুড়ে হোঁচট খায় তবে এই প্রশ্নটি এখানে দেখুন: জেনেরিক অভিধানের ক্ষেত্রে সংবেদনশীল অ্যাক্সেস
রোবটনিক

এটা সত্যিই চমৎকার হবে; কেস-সংবেদনশীল সংস্করণ হিসাবে ~=সমান্তরাল সম্পর্কিত কোনও সংজ্ঞায়িত করতে বলুন ==
ইডিলন

মাইক্রোসফ্ট বিকাশকারীরা যদি এটি দেখেন তবে আমি মনে করি সিশার্পের পরবর্তী সংস্করণে কেস-সংবেদনশীল অপারেটরের প্রয়োজন আছে। এই স্ট্রিং.একুয়াল () দীর্ঘ।
রেজ.নেট

উত্তর:


288

এটা চেষ্টা কর:

string.Equals(a, b, StringComparison.CurrentCultureIgnoreCase);

আমি একটি স্ট্যাকওভারফ্লো আপু নবাগত - আপনি একটি লিঙ্ক যুক্ত করে কী বোঝাতে চান তা ব্যাখ্যা করতে পারেন? আপনি কি এমএসডিএন ডক্সকে বোঝাতে চান?
জন Feminella

55
আপনি যদি সংস্কৃতি সংবেদনশীল তুলনা করতে চান তবে এই পদ্ধতিটি ব্যবহার করুন। যদি আপনি কেবল "ফাইল" এবং "ফাইল" উভয়ই গৃহীত হয়েছে তা নিশ্চিত করতে চান তবে "অর্ডিনালআইগনরেসেস" ব্যবহার করুন বা আপনার কোডটি তুর্কি লোকেলের মতো জায়গায় কাজ করতে পারে না। আরও তথ্যের জন্য, মোসারওয়্যার.com
জেফ মোসার 19

10
স্যামুয়েল কী বিষয়ে কথা বলছে তা নিশ্চিত নয় ... এই উত্তরটি নিখুঁত। এটি সঠিক এবং স্ব-ব্যাখ্যামূলক। এটির কোনও রেফারেন্স দরকার নেই। +1
সেলিং জুডো

3
আঃ এই রকম ভয়াবহ মুখ! আমার কীবোর্ডটি শেষ হয়ে যাবে। সেই দিনগুলি হয়ে গেছে যখন আমি ব্যবহার করতে পারি " if A$=B$ then goto 10"
সঞ্জয় মনোহর

9
@ সঞ্জয় মনোহর তারপরে একটি কাস্টম অপারেটর লিখুন - এবং আমি আরও ভাল কীবোর্ডের পরামর্শ দেব।
রাশিও

37

সবচেয়ে ভালো উপায় বর্ণের ক্ষেত্রে উপেক্ষা 2 স্ট্রিং তুলনা করতে ব্যবহার করা String.Equals স্ট্যাটিক পদ্ধতি উল্লেখ একটি পূরণবাচক ক্ষেত্রে স্ট্রিং তুলনা উপেক্ষা করি। এটি স্ট্রিংগুলি লোয়ার বা উপরের ক্ষেত্রে রূপান্তর করার এবং তার পরে তার সাথে তুলনা করার চেয়েও দ্রুততম উপায়।

আমি উভয় পদ্ধতির পারফরম্যান্স পরীক্ষা করেছি এবং অর্ডিনাল উপেক্ষা কেস স্ট্রিং তুলনা 9 গুণ বেশি দ্রুত ছিল ! এটি স্ট্রিংগুলি লোয়ার বা আপার ক্ষেত্রে রূপান্তর করার চেয়ে আরও নির্ভরযোগ্য (তুর্কি আই সমস্যাটি দেখুন)। সুতরাং সমতার জন্য স্ট্রিংগুলির তুলনা করতে সর্বদা স্ট্রিং.একুয়ালস পদ্ধতি ব্যবহার করুন :

String.Equals(string1, string2, StringComparison.OrdinalIgnoreCase);

আপনি যদি সংস্কৃতি নির্দিষ্ট স্ট্রিং তুলনা করতে চান তবে আপনি নীচের কোডটি ব্যবহার করতে পারেন:

String.Equals(string1, string2, StringComparison.CurrentCultureIgnoreCase);

দয়া করে মনে রাখবেন যে দ্বিতীয় উদাহরণটি বর্তমান সংস্কৃতির স্ট্রিং তুলনা যুক্তি ব্যবহার করে, যা এটি প্রথম উদাহরণের তুলনায় "অর্ডিনাল উপেক্ষা" এর তুলনায় ধীর করে তোলে, সুতরাং আপনার যদি কোনও সংস্কৃতির নির্দিষ্ট স্ট্রিং তুলনা যুক্তির প্রয়োজন না হয় এবং আপনি সর্বাধিক পারফরম্যান্সের পরে, "অর্ডিনাল উপেক্ষা কেস" তুলনা ব্যবহার করুন।

আরও তথ্যের জন্য, আমার ব্লগে পুরো গল্পটি পড়ুন


1
প্রস্তাব করবেন না ToLowerবা ToLowerInvariant: তারা কেবল তুলনা করার জন্য মেমরি তৈরি করে এবং ইউনিকোডে নতুন অক্ষর সেট যুক্ত হওয়ার সাথে সাথে তারা ব্যর্থ হতে পারে। ToUpperঅন্যদের মধ্যে তুর্কি 'আমি' এর কারণে ব্যর্থ হয়; ToLowerভবিষ্যতে অনুরূপ কারণে ব্যর্থ হওয়ার কোনও কারণ নেই ।
এন্টিডিউহ

@ এন্টিদহ, আপনার মন্তব্যের জন্য আপনাকে ধন্যবাদ আমাদের বেশিরভাগই এই সম্ভাব্য সমস্যাগুলি সম্পর্কে সচেতন, ইন্টারনেটে অনেক টিউটোরিয়াল উদাহরণ হিসাবে তুর্কি 'আই' দেয়। আপনি যেমন আমার পোস্টে দেখতে পাচ্ছেন, আমি ব্যবহার ToLowerবা ToLowerInvariantপদ্ধতিগুলি ব্যবহার করার পরামর্শ দিচ্ছি না , আমি কেবল String.Equalsপদ্ধতিটি আরও দক্ষতার সাথে দেখাতে চেয়েছিলাম ।
পাভেল ভ্লাদভ

3
"আমাদের বেশিরভাগই এই সম্ভাব্য সমস্যাগুলি সম্পর্কে সচেতন, ইন্টারনেটে অনেক টিউটোরিয়াল তুর্কি 'আই' কে উদাহরণ হিসাবে দেয়" - যথেষ্ট লোক নেই, এবং আপনি এখনও এটিকে আপনার উত্তরের দ্বিতীয় বাক্য হিসাবে উল্লেখ করছেন। তদুপরি, আপনার উত্তরে এটি কখনও ব্যবহার না করার পর্যাপ্ত সমর্থনযোগ্যতা অন্তর্ভুক্ত নয় - আপনি কেবল কর্মক্ষমতা উল্লেখ করেছেন; কর্মক্ষমতা সর্বদা চূড়ান্ত অগ্রাধিকার হয় না। ফলস্বরূপ, আপনি বর্তমানে সহায়তা কেন্দ্রের নির্দেশিকা লঙ্ঘন করছেন; বাহ্যিক সাইটগুলির লিঙ্কগুলি ভাল, তবে আপনি পর্যাপ্ত পরিমাণে সংক্ষিপ্ত বিবরণ দেননি (তুর্কি 'আমি' সমস্যা)। এসও আপনার বিজ্ঞাপনের প্ল্যাটফর্ম নয়।
এন্টিডহ

20

StringComparerস্ট্যাটিক শ্রেণিতে এমন অনেকগুলি সম্পত্তি রয়েছে যা আপনি যে কোনও ধরণের কেস-সংবেদনশীলতার জন্য তুলনামূলককে ফিরিয়ে নিতে পারেন:

StringComparer প্রোপার্টি

উদাহরণস্বরূপ, আপনি কল করতে পারেন

StringComparer.CurrentCultureIgnoreCase.Equals(string1, string2)

অথবা

StringComparer.CurrentCultureIgnoreCase.Compare(string1, string2)

এটা তোলে চেয়ে একটু ক্লিনার এর string.Equalsবা string.Compareoverloads করে একটি নিতে StringComparisonযুক্তি।


15
System.Collections.CaseInsensitiveComparer

অথবা

System.StringComparer.OrdinalIgnoreCase

এই পুরো প্রয়োগ প্রয়োগ করে?
গেটকিলার

3
আমি এই বিষয়ে আরও তথ্য কোথায় পেতে পারি। এর অর্থ কি আমি কেস সংবেদনশীল মিলের জন্য ব্যবহার করতে পারি ==?
গেটকিলার


8

অথবা

if (StringA.Equals(StringB, StringComparison.CurrentCultureIgnoreCase)) {

তবে আপনার নিশ্চিত হওয়া দরকার যে স্ট্রিংএ নাল নয়। তাই সম্ভবত তু ব্যবহার আরও ভাল:

string.Equals(StringA , StringB, StringComparison.CurrentCultureIgnoreCase);

জন পরামর্শ হিসাবে

সম্পাদনা: বাগ সংশোধন করা হয়েছে



3

অপারেটর? না, তবে আমি মনে করি আপনি আপনার সংস্কৃতি পরিবর্তন করতে পারেন যাতে স্ট্রিং তুলনাটি কেস-সংবেদনশীল না হয়।

// you'll want to change this...
System.Threading.Thread.CurrentThread.CurrentCulture
// and you'll want to custimize this
System.Globalization.CultureInfo.CompareInfo

আমি বিশ্বাস করি যে এটি সমান অপারেটরের সাথে যেভাবে স্ট্রিংগুলি তুলনা করা হচ্ছে সেভাবে পরিবর্তিত হবে।


হ্যাঁ, খুব কমপক্ষে বলতে গেলে এটি পুরোপুরি নয় যা আপনি করতে চান যদি না আপনি সমস্ত স্ট্রিং তুলনা কে সংবেদনশীল হতে চান। তবে আমি মনে করি এটি সমান অপারেটরের আচরণকে পরিবর্তন করে।
জন লিডেগ্রেন

3

বাক্য গঠনটি সহজ করার জন্য এখানে একটি ধারণা:

public class IgnoreCase
{
    private readonly string _value;

    public IgnoreCase(string s)
    {
        _value = s;
    }

    protected bool Equals(IgnoreCase other)
    {
        return this == other;
    }

    public override bool Equals(object obj)
    {
        return obj != null &&
               (ReferenceEquals(this, obj) || (obj.GetType() == GetType() && this == (IgnoreCase) obj));
    }

    public override int GetHashCode()
    {
        return _value?.GetHashCode() ?? 0;
    }

    public static bool operator ==(IgnoreCase a, IgnoreCase b)
    {
        return string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
    }

    public static bool operator !=(IgnoreCase a, IgnoreCase b)
    {
        return !(a == b);
    }

    public static implicit operator string(IgnoreCase s)
    {
        return s._value;
    }

    public static implicit operator IgnoreCase(string s)
    {
        return new IgnoreCase(s);
    }
}

ব্যবহারযোগ্য:

Console.WriteLine((IgnoreCase) "a" == "b"); // false
Console.WriteLine((IgnoreCase) "abc" == "abC"); // true
Console.WriteLine((IgnoreCase) "Abc" == "aBc"); // true
Console.WriteLine((IgnoreCase) "ABC" == "ABC"); // true

যদিও আমি পরিষ্কার দেখতে ব্যবহারের বাক্য গঠনটি পছন্দ করি, এটি কিছুটা বিভ্রান্তিমূলক ( IgnoreCaseবনাম IgnoreCaseString) এবং অস্পষ্ট (জাভা ইমপ্লিট আনবক্সিং বনাম ইম্পিলিটেড বক্সিং বাছাই করে তাই আমি বিশ্বাস করি যে এটি জাভাতে সেখানে স্ট্রিংয়ে ফিরে আসার সাথে কাজ করবে না)। এবং এটি প্রতিটি নতুন তুলনা করার জন্য কল ট্রি প্রয়োগের সাথে 2 টি নতুন অবজেক্টের মেমরির ওভারহেড তৈরি করে প্রদর্শিত ব্যবহারের ক্ষেত্রে বিভিন্ন নেস্টেড পদ্ধতিতে কল করে। এটি বলেছিল, বেশিরভাগ ক্ষেত্রে পারফরম্যান্স সম্ভবত যথেষ্ট ভাল।
আরকাইন 55

যদিও এটি একটি চতুর ধারণা, এটি রক্ষণাবেক্ষণের দৃষ্টিভঙ্গি থেকে সত্যই বুদ্ধিমানের কাজ নয়। আপনি সিস্টেমের অন্তর্নির্মিত স্ট্রিং প্রকারটি ব্যবহার না করে কার্যকরভাবে একটি সারোগেট স্ট্রিং টাইপ তৈরি করছেন। প্রোগ্রামার-পরে-আসবে বুঝতে পারবে না কী এক নজরে চলছে এবং তারপরে সে আপনাকে উপুড় করবে। স্ট্রিং.একুয়ালস () ব্যবহার করা আসলে খুব খারাপ কিছু নয় এবং বেশিরভাগ লোকেরা বুঝতে পারে যে এটি কী করছে।
ntcolonel

1

আমি এই তুলনা পদ্ধতি শেষে টাইপ করতে অভ্যস্ত: , StringComparison.

তাই আমি একটি এক্সটেনশন করেছি।

namespace System
{   public static class StringExtension
    {
        public static bool Equals(this string thisString, string compareString,
             StringComparison stringComparison)
        {
            return string.Equals(thisString, compareString, stringComparison);
        }
    }
}

কেবলমাত্র নোট করুন যে আপনার thisStringএক্সট্রা কল করার আগে নাল পরীক্ষা করতে হবে ।


1
বর্তমান .NET ফ্রেমওয়ার্ক সংস্করণগুলিতে কি এই বিল্ট-ইন পদ্ধতিটির মতো? ডকস.মাইক্রোসফট.ইন- জিবি
বার্নার্ড ভ্যান্ডার বেকেন

1
তাই উপস্থিত। । নেট এর পরবর্তী সংস্করণগুলি এখন এটি অন্তর্ভুক্ত করে।
ভালামাস

.NET 4.5 এবং সমস্ত .NET মূল সংস্করণ থেকে উপলব্ধ।
বার্নার্ড ভ্যান্ডার বেকেন


0
if (StringA.ToUpperInvariant() == StringB.ToUpperInvariant()) {

লোকেদের প্রতিবেদন ToUpperInvariant () ToLowerInvariant () এর চেয়ে দ্রুত।


1
যদি বর্তমান বা কাঙ্ক্ষিত সংস্কৃতিতে আপার-কেসিংয়ের জন্য বিশেষ নিয়ম থাকে তবে ইনগ্রেন্টেন্ট একটি খারাপ ধারণা হতে পারে।
ওরেগনহোস্ট

এটি কি প্রতিটি স্ট্রিংয়ের একটি নতুন অনুলিপি তৈরি করে? যদি তাই হয়, খারাপ ধারণা।
সিজেকে

1
যদি উভয় (বা উভয়) স্ট্রিং নাল হয় তবে এটিও একটি ব্যতিক্রম ছুঁড়ে ফেলবে।
tvanfosson

3
পারফরম্যান্স অনুযায়ী, এটি এত ভাল সমাধান নয় কারণ আপনি এখানে 2 টি নতুন স্ট্রিং উদাহরণ তৈরি করবেন।
ফ্রেডেরিক গেইসেলস

0

অন্যদের উত্তরগুলি এখানে সম্পূর্ণ বৈধ, তবে কোনওভাবে এটি টাইপ করতে StringComparison.OrdinalIgnoreCaseএবং ব্যবহার করতে কিছুটা সময় নেয় String.Compare

আমি সরল স্ট্রিং এক্সটেনশন পদ্ধতিটি কোড করে রেখেছি, যেখানে তুলনাটি কেস সংবেদনশীল বা বুলিয়ানয়ের সাথে সংজ্ঞাহীন ক্ষেত্রে উল্লেখ করা যেতে পারে - নিম্নলিখিত উত্তরটি দেখুন:

https://stackoverflow.com/a/49208128/2338477

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