क्या सी # में अध्यादेश बनाने का एक आसान तरीका है?


202

क्या संख्या के लिए Ordinals बनाने के लिए C # में एक आसान तरीका है ? उदाहरण के लिए:

  • 1 रिटर्न 1
  • 2 रिटर्न 2
  • 3 रिटर्न 3
  • ...आदि

क्या ऐसा किया जा सकता है String.Format()या ऐसा करने के लिए कोई कार्य उपलब्ध हैं?

जवाबों:


310

यह पृष्ठ आपको सभी कस्टम संख्यात्मक प्रारूपण नियमों की पूरी सूची देता है:

http://msdn.microsoft.com/en-us/library/0c899ak8.aspx

जैसा कि आप देख सकते हैं, वहाँ अध्यादेशों के बारे में कुछ भी नहीं है, इसलिए इसे String.Format का उपयोग करके नहीं किया जा सकता है। हालांकि यह वास्तव में यह करने के लिए एक समारोह लिखने के लिए मुश्किल नहीं है।

public static string AddOrdinal(int num)
{
    if( num <= 0 ) return num.ToString();

    switch(num % 100)
    {
        case 11:
        case 12:
        case 13:
            return num + "th";
    }

    switch(num % 10)
    {
        case 1:
            return num + "st";
        case 2:
            return num + "nd";
        case 3:
            return num + "rd";
        default:
            return num + "th";
    }
}

अपडेट: तकनीकी रूप से अध्यादेश <= 0 के लिए मौजूद नहीं है, इसलिए मैंने ऊपर कोड अपडेट किया है। बेमानी को भी हटा दियाToString() तरीकों ।

यह भी ध्यान दें, यह अंतर्राष्ट्रीयकरण नहीं है। मुझे नहीं पता कि अन्य भाषाओं की तरह अध्यादेश कैसा दिखता है।


2
Assert.AreEqual ("0", AddOrdinal (0)); देखें बुद्धिमानीजी ।.com
what-

2
एक्स्टेंशन मेथड (या इसे जो भी कहते हैं - See @ Stu's answer) का उपयोग करना यहाँ बहुत अच्छा काम करेगा। @ एसआई, यदि आवश्यक हो तो उस शर्त को जोड़ना बहुत आसान होगा।
स्ट्रैजर

12
'11 वीं, 12 वीं 13 वीं' के बारे में भूल गए ... एक साक्षात्कार प्रश्न होना चाहिए। :-)
होल्फ

2
हाँ, अच्छी तरह से प्रोग्रामर अजीब हैं;)
संजूसन

2
@IanWarburton कोई अतिरेक नहीं है क्योंकि केवल एक ही रिटर्न स्टेटमेंट हिट होगा। यदि आप उत्तर से खुश नहीं हैं, तो कृपया अपनी आपूर्ति करें, ऐसा करने के लिए "उचित" तरीका दिखाते हुए, और यह क्यों मायने रखता है।
B2K

73

अंतर्राष्ट्रीयकरण याद रखें!

यहां समाधान केवल अंग्रेजी के लिए काम करते हैं। यदि आपको अन्य भाषाओं का समर्थन करने की आवश्यकता है, तो चीजें बहुत अधिक जटिल हो जाती हैं।

उदाहरण के लिए, स्पैनिश "1st" में "1.o", "1.a", "1.os" या "1.as" लिखा जाएगा, इस बात पर निर्भर करता है कि आप जिस चीज़ की गिनती कर रहे हैं वह मर्दाना, स्त्री या बहुवचन है !

इसलिए यदि आपके सॉफ़्टवेयर को विभिन्न भाषाओं का समर्थन करने की आवश्यकता है, तो अध्यादेशों से बचने का प्रयास करें।


7
@ एंडोमर: "पहले 2 पाठकों" => इतालवी (और स्पेनिश में भी, मुझे लगता है) "पहला" यहां बहुवचन है। तो आपके पास एकवचन पुल्लिंग, एकवचन स्त्रीलिंग, बहुवचन पुल्लिंग, बहुवचन स्त्रीलिंग है; शायद कुछ भाषा में एक तटस्थ मामला भी है (पुरुषों / जानवरों से अलग बातें)
एम। तुरैनी

2
कहा कि, आपको अध्यादेशों से बचने की ज़रूरत नहीं है: उन्हें स्थानीयकरण में शामिल करें, एक बार जब आप जानते हैं कि आप सभी मामले का सामना कर सकते हैं, या (अपने ग्राहक को) कुछ सीमाओं को स्वीकार कर सकते हैं।
एम। तुरतिनी

26
यह बताता है कि क्यों .NET टीम ने इसे डेटटाइम फॉर्मेटर्स में जोड़ने के लिए स्पष्ट किया
क्रिस एस

पल.जेएस में लोकल द्वारा "ऑर्डिनल" फॉर्मेटिंग फंक्शन है, इसलिए यह उल्लेखनीय लगता है, काश उन्होंने डेटटाइम के लिए .NET में भी किया होता
Guillaume86

5
यह बहुत सरल होगा यदि आप सभी "का उपयोग करते हैं।" अध्यादेशियों के लिए चरित्र, जैसे हम जर्मन में करते हैं)))) 1. 2. 3. 3. 4. 5., हालाँकि एल्गोरिथ्म इतना अधिक दिलचस्प होगा कि अगर कोई नंबर लिखता है, और उसे 4 में विभक्त करना होगा 12 अलग-अलग संयोजनों के विलक्षण और बहुवचन मामलों के अलावा 3 अलग-अलग लेखों के साथ व्याकरणिक मामले। यह सोचने के लिए आओ, रूसियों के पास 2 और नहीं हैं, प्लस वोकैटिव, और कुछ नॉर्डिक भाषाओं में 15 हैं, मुझे लगता है। मैं .NET में उस कार्यान्वयन को देखना पसंद करूंगा।
स्टीफन स्टीगर

22

मेरे संस्करण जेसी के संस्करण स्टू के और समजू के संस्करण :)

इकाई परीक्षण में यह दिखाने के लिए कि स्वीकृत उत्तर गलत है जब संख्या <1

    /// <summary>
    /// Get the ordinal value of positive integers.
    /// </summary>
    /// <remarks>
    /// Only works for english-based cultures.
    /// Code from: http://stackoverflow.com/questions/20156/is-there-a-quick-way-to-create-ordinals-in-c/31066#31066
    /// With help: http://www.wisegeek.com/what-is-an-ordinal-number.htm
    /// </remarks>
    /// <param name="number">The number.</param>
    /// <returns>Ordinal value of positive integers, or <see cref="int.ToString"/> if less than 1.</returns>
    public static string Ordinal(this int number)
    {
        const string TH = "th";
        string s = number.ToString();

        // Negative and zero have no ordinal representation
        if (number < 1)
        {
            return s;
        }

        number %= 100;
        if ((number >= 11) && (number <= 13))
        {
            return s + TH;
        }

        switch (number % 10)
        {
            case 1: return s + "st";
            case 2: return s + "nd";
            case 3: return s + "rd";
            default: return s + TH;
        }
    }

    [Test]
    public void Ordinal_ReturnsExpectedResults()
    {
        Assert.AreEqual("-1", (1-2).Ordinal());
        Assert.AreEqual("0", 0.Ordinal());
        Assert.AreEqual("1st", 1.Ordinal());
        Assert.AreEqual("2nd", 2.Ordinal());
        Assert.AreEqual("3rd", 3.Ordinal());
        Assert.AreEqual("4th", 4.Ordinal());
        Assert.AreEqual("5th", 5.Ordinal());
        Assert.AreEqual("6th", 6.Ordinal());
        Assert.AreEqual("7th", 7.Ordinal());
        Assert.AreEqual("8th", 8.Ordinal());
        Assert.AreEqual("9th", 9.Ordinal());
        Assert.AreEqual("10th", 10.Ordinal());
        Assert.AreEqual("11th", 11.Ordinal());
        Assert.AreEqual("12th", 12.Ordinal());
        Assert.AreEqual("13th", 13.Ordinal());
        Assert.AreEqual("14th", 14.Ordinal());
        Assert.AreEqual("20th", 20.Ordinal());
        Assert.AreEqual("21st", 21.Ordinal());
        Assert.AreEqual("22nd", 22.Ordinal());
        Assert.AreEqual("23rd", 23.Ordinal());
        Assert.AreEqual("24th", 24.Ordinal());
        Assert.AreEqual("100th", 100.Ordinal());
        Assert.AreEqual("101st", 101.Ordinal());
        Assert.AreEqual("102nd", 102.Ordinal());
        Assert.AreEqual("103rd", 103.Ordinal());
        Assert.AreEqual("104th", 104.Ordinal());
        Assert.AreEqual("110th", 110.Ordinal());
        Assert.AreEqual("111th", 111.Ordinal());
        Assert.AreEqual("112th", 112.Ordinal());
        Assert.AreEqual("113th", 113.Ordinal());
        Assert.AreEqual("114th", 114.Ordinal());
        Assert.AreEqual("120th", 120.Ordinal());
        Assert.AreEqual("121st", 121.Ordinal());
        Assert.AreEqual("122nd", 122.Ordinal());
        Assert.AreEqual("123rd", 123.Ordinal());
        Assert.AreEqual("124th", 124.Ordinal());
    }

15

सरल, स्वच्छ, त्वरित

    private static string GetOrdinalSuffix(int num)
    {
        if (num.ToString().EndsWith("11")) return "th";
        if (num.ToString().EndsWith("12")) return "th";
        if (num.ToString().EndsWith("13")) return "th";
        if (num.ToString().EndsWith("1")) return "st";
        if (num.ToString().EndsWith("2")) return "nd";
        if (num.ToString().EndsWith("3")) return "rd";
        return "th";
    }

या विस्तार विधि के रूप में अभी तक बेहतर है

public static class IntegerExtensions
{
    public static string DisplayWithSuffix(this int num)
    {
        if (num.ToString().EndsWith("11")) return num.ToString() + "th";
        if (num.ToString().EndsWith("12")) return num.ToString() + "th";
        if (num.ToString().EndsWith("13")) return num.ToString() + "th";
        if (num.ToString().EndsWith("1")) return num.ToString() + "st";
        if (num.ToString().EndsWith("2")) return num.ToString() + "nd";
        if (num.ToString().EndsWith("3")) return num.ToString() + "rd";
        return num.ToString() + "th";
    }
}

अब आप सिर्फ कॉल कर सकते हैं

int a = 1;
a.DisplayWithSuffix(); 

या यहां तक ​​कि के रूप में प्रत्यक्ष

1.DisplayWithSuffix();

14

आपको अपना रोल खुद करना होगा। मेरे सिर के ऊपर से:

public static string Ordinal(this int number)
{
  var work = number.ToString();
  if ((number % 100) == 11 || (number % 100) == 12 || (number % 100) == 13)
    return work + "th";
  switch (number % 10)
  {
    case 1: work += "st"; break;
    case 2: work += "nd"; break;
    case 3: work += "rd"; break;
    default: work += "th"; break;
  }
  return work;
}

आप तब कर सकते हैं

Console.WriteLine(432.Ordinal());

11/12/13 अपवाद के लिए संपादित। मैं अपने सिर के ऊपर से कह रहा हूँ :-)

1011 के लिए संपादित - अन्य लोगों ने इसे पहले ही तय कर दिया है, बस यह सुनिश्चित करना चाहते हैं कि अन्य लोग इस गलत संस्करण को न पकड़ें।


12

मुझे स्टु के और समजेडसन के समाधान दोनों के तत्व पसंद थे और मुझे लगता है कि यह एक उपयोगी कॉम्बो है।

    public static string Ordinal(this int number)
    {
        const string TH = "th";
        var s = number.ToString();

        number %= 100;

        if ((number >= 11) && (number <= 13))
        {
            return s + TH;
        }

        switch (number % 10)
        {
            case 1:
                return s + "st";
            case 2:
                return s + "nd";
            case 3:
                return s + "rd";
            default:
                return s + TH;
        }
    }

1
"वें" के लिए एक स्थिरांक का उपयोग करने के पीछे तर्क क्या है?
निक सिप

क्योंकि यह कोड में दो बार उपयोग किया जाता है। बस उम्र-पुराने ज्ञान का उपयोग करना जो आपको खुद को दोहराना नहीं चाहिए :) इस मामले में, .NET रनटाइम को केवल स्ट्रिंग की एक प्रति बनाना चाहिए जबकि कोड में दो "वें" के साथ, दो तार पैदा होंगे और स्मृति में संदर्भित।
जेसी सी। स्लीपर

25
और यह भी, यदि TH का मान कभी बदलता है, तो आपको सेट किया जाएगा।
ग्रहण

7
@ जेसे - आपको मेरा +1 मिलता है, लेकिन मुझे विश्वास नहीं होता है कि .NET इस तरह से स्ट्रिंग संभालता है, देखिए yoda.arachsys.com/csharp/strings.html#interning , मेरा पढ़ना "वें" शाब्दिक अर्थ के संदर्भ में है स्मृति के एक ही बिट का संदर्भ होगा। लेकिन मैं DRY के बारे में सहमत हूं :)
si618

4
इस तरह दोहराव को हटाने से मुझे लगता है कि पठनीयता में बाधा आती है, इसलिए भ्रम "व्हाई द थे?"। मुझे नहीं लगता कि DRY की व्याख्या की जानी चाहिए क्योंकि 'सभी दोहराव को दूर करें जो भी लागत हो'।
SeeNoWeevil

8

हालांकि मैंने इसे अभी तक बेंचमार्क नहीं किया है, आपको सभी सशर्त केस स्टेटमेंट से बचकर बेहतर प्रदर्शन करने में सक्षम होना चाहिए।

यह जावा है, लेकिन C # के लिए एक बंदरगाह तुच्छ है:

public class NumberUtil {
  final static String[] ORDINAL_SUFFIXES = {
    "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th"
  };

  public static String ordinalSuffix(int value) {
    int n = Math.abs(value);
    int lastTwoDigits = n % 100;
    int lastDigit = n % 10;
    int index = (lastTwoDigits >= 11 && lastTwoDigits <= 13) ? 0 : lastDigit;
    return ORDINAL_SUFFIXES[index];
  }

  public static String toOrdinal(int n) {
    return new StringBuffer().append(n).append(ordinalSuffix(n)).toString();
  }
}

ध्यान दें, सशर्त की कमी और सरणी लुकअप के उपयोग को तेज लूप में बहुत सारे अध्यादेश उत्पन्न करने पर प्रदर्शन को गति देना चाहिए। हालाँकि, मैंने यह भी माना कि यह केस स्टेटमेंट सॉल्यूशन जितना पठनीय नहीं है।


क्षमा करें कि मैंने इसे C # में बेंचमार्क किया, आपका संस्करण si618 के समाधान से अधिक तेज़ नहीं है।
GY_

इस उत्तर की जाँच करें stackoverflow.com/a/58378465/2583579 कुछ बेंचमार्क के लिए
Dan Dohotaru

3

रयान के समाधान के समान, लेकिन इससे भी अधिक बुनियादी, मैं सिर्फ एक सादे सरणी का उपयोग करता हूं और सही ऑर्डिनल देखने के लिए दिन का उपयोग करता हूं:

private string[] ordinals = new string[] {"","st","nd","rd","th","th","th","th","th","th","th","th","th","th","th","th","th","th","th","th","th","st","nd","rd","th","th","th","th","th","th","th","st" };
DateTime D = DateTime.Now;
String date = "Today's day is: "+ D.Day.ToString() + ordinals[D.Day];

मुझे जरूरत नहीं थी, लेकिन मुझे लगता है कि यदि आप एक से अधिक भाषा समर्थन चाहते हैं तो आप एक बहुआयामी सरणी का उपयोग कर सकते हैं।

मैं अपने यूनी दिनों से जो कुछ भी याद रख सकता हूं, इस विधि के लिए सर्वर से न्यूनतम प्रयास की आवश्यकता है।


2

मैं इस एक्सटेंशन क्लास का उपयोग करता हूं:

public static class Int32Extensions
{
    public static string ToOrdinal(this int i)
    {
        return (i + "th")
            .Replace("1th", "1st")
            .Replace("2th", "2nd")
            .Replace("3th", "3rd");
    }
}

११ वाँ, १२ वाँ, १३
वाँ

2

अनुरोध "सामंजस्य के कम अतिरेक" संस्करण ...

public static string AddOrdinal(int number)
{
    if (number <= 0) return number.ToString();

    string GetIndicator(int num)
    {
        switch (num % 100)
        {
            case 11:
            case 12:
            case 13:
                return "th";
        }

        switch (num % 10)
        {
            case 1:
                return "st";
            case 2:
                return "nd";
            case 3:
                return "rd";
            default:
                return "th";
        }
    }

    return number + GetIndicator(number);
}

2
मैं "GetIndicator" को एक के रूप में उजागर करूँगा public staticऔर इसे एक अधिक नामी नाम (अर्थात "ऑर्डिनलसफ़िक्स") का नाम दूंगा। कॉल करने वाला अलग-अलग प्रारूपों (यानी अल्पविरामों के साथ) में भाग चाह सकता है।
टॉम

2
        private static string GetOrd(int num) => $"{num}{(!(Range(11, 3).Any(n => n == num % 100) ^ Range(1, 3).All(n => n != num % 10)) ? new[] { "ˢᵗ", "ⁿᵈ", "ʳᵈ" }[num % 10 - 1] : "ᵗʰ")}";

अगर किसी को एक लाइनर की तलाश है: पी


1
public static string OrdinalSuffix(int ordinal)
{
    //Because negatives won't work with modular division as expected:
    var abs = Math.Abs(ordinal); 

    var lastdigit = abs % 10; 

    return 
        //Catch 60% of cases (to infinity) in the first conditional:
        lastdigit > 3 || lastdigit == 0 || (abs % 100) - lastdigit == 10 ? "th" 
            : lastdigit == 1 ? "st" 
            : lastdigit == 2 ? "nd" 
            : "rd";
}

1

संपादित करें : जैसा कि YM_Indenders टिप्पणी में बताते हैं , samjudson का उत्तर 1000 से अधिक संख्याओं के लिए काम करता है, निकफ की टिप्पणी चली गई है, और मुझे याद नहीं है कि मैंने जो समस्या देखी थी। तुलनात्मक समय के लिए इस उत्तर को यहाँ छोड़ दें।

इनमें से एक भयानक बहुत संख्या के लिए काम नहीं करते> 999, के रूप में nickf ने एक टिप्पणी में बताया है (EDIT: अब गायब है)।

यहाँ एक संस्करण है जो कि समजू के स्वीकृत उत्तर के संशोधित संस्करण पर आधारित है।

public static String GetOrdinal(int i)
{
    String res = "";

    if (i > 0)
    {
        int j = (i - ((i / 100) * 100));

        if ((j == 11) || (j == 12) || (j == 13))
            res = "th";
        else
        {
            int k = i % 10;

            if (k == 1)
                res = "st";
            else if (k == 2)
                res = "nd";
            else if (k == 3)
                res = "rd";
            else
                res = "th";
        }
    }

    return i.ToString() + res;
}

इसके अलावा शहजाद कुरैशी का जवाब , स्ट्रिंग हेरफेर का उपयोग करके ठीक काम करता है, हालांकि इसमें एक प्रदर्शन जुर्माना है। इनमें से कई को उत्पन्न करने के लिए, एक LINQPad उदाहरण कार्यक्रम इस पूर्णांक की तुलना में स्ट्रिंग संस्करण 6-7 गुना धीमा बनाता है (हालांकि आपको नोटिस करने के लिए बहुत कुछ पैदा करना होगा)।

LINQPad उदाहरण:

void Main()
{
    "Examples:".Dump();

    foreach(int i in new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 22, 113, 122, 201, 202, 211, 212, 2013, 1000003, 10000013 })
        Stuff.GetOrdinal(i).Dump();

    String s;

    System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();

    for(int iter = 0; iter < 100000; iter++)
        foreach(int i in new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 22, 113, 122, 201, 202, 211, 212, 2013, 1000003, 1000013 })
            s = Stuff.GetOrdinal(i);

    "Integer manipulation".Dump();
    sw.Elapsed.Dump();

    sw.Restart();

    for(int iter = 0; iter < 100000; iter++)
        foreach(int i in new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 22, 113, 122, 201, 202, 211, 212, 2013, 1000003, 1000013 })
            s = (i.ToString() + Stuff.GetOrdinalSuffix(i));

    "String manipulation".Dump();
    sw.Elapsed.Dump();
}

public class Stuff
{
        // Use integer manipulation
        public static String GetOrdinal(int i)
        {
                String res = "";

                if (i > 0)
                {
                        int j = (i - ((i / 100) * 100));

                        if ((j == 11) || (j == 12) || (j == 13))
                                res = "th";
                        else
                        {
                                int k = i % 10;

                                if (k == 1)
                                        res = "st";
                                else if (k == 2)
                                        res = "nd";
                                else if (k == 3)
                                        res = "rd";
                                else
                                        res = "th";
                        }
                }

                return i.ToString() + res;
        }

        // Use string manipulation
        public static string GetOrdinalSuffix(int num)
        {
                if (num.ToString().EndsWith("11")) return "th";
                if (num.ToString().EndsWith("12")) return "th";
                if (num.ToString().EndsWith("13")) return "th";
                if (num.ToString().EndsWith("1")) return "st";
                if (num.ToString().EndsWith("2")) return "nd";
                if (num.ToString().EndsWith("3")) return "rd";
                return "th";
        }
}

मुझे @ नीक की टिप्पणी नहीं मिल रही है, समजसन के जवाब में क्या गलत है? यह मुझे ऐसा लगता है जैसे यह 1000 से ऊपर की संख्या को ठीक करता है जबकि आपकी तुलना में बहुत अधिक पठनीय है।
जोशुआ वाल्श

1
यह एक उचित टिप्पणी है, मैंने अभी एक परीक्षण सेट चलाया और मुझे कोई समस्या नहीं मिली। ऐसा प्रतीत नहीं होता कि सैम के उत्तर के लिए कोई संपादन किया गया है इसलिए मैं केवल कल्पना कर सकता हूं कि मैं पागल हो रहा था। मैंने अपना उत्तर संपादित कर दिया है।
भेलाकहोलिज्म

1
हाहा, हम सभी के पास ऐसे क्षण हैं जैसे हम नहीं? हम पुराने कोड को देखते हैं और जाते हैं "मैंने इसे क्यों लिखा?"
जोशुआ वॉल्श

1

अन्य उत्तरों के आधार पर:

public static string Ordinal(int n)
{   
    int     r = n % 100,     m = n % 10;

    return (r<4 || r>20) && (m>0 && m<4) ? n+"  stndrd".Substring(m*2,2) : n+"th";                                              
}

3
1ST स्थान: सबसे अनावश्यक रूप से गुप्त उत्तर। "अनावश्यक रूप से": कोड आकार / प्रदर्शन लाभ पठनीय लागत के लायक नहीं है। "क्रिप्टिक": "लेपर्सन" आवश्यकताओं के मानचित्र में महत्वपूर्ण अनुवाद की आवश्यकता।
टॉम

0

एमएसआई-एसक्यूएल के लिए एफडब्ल्यूआईडब्ल्यू, यह अभिव्यक्ति काम करेगी। पहले WHEN ( WHEN num % 100 IN (11, 12, 13) THEN 'th') को सूची में पहले वाले के रूप में रखें , क्योंकि यह दूसरों के सामने कोशिश करने पर निर्भर करता है।

CASE
  WHEN num % 100 IN (11, 12, 13) THEN 'th' -- must be tried first
  WHEN num % 10 = 1 THEN 'st'
  WHEN num % 10 = 2 THEN 'nd'
  WHEN num % 10 = 3 THEN 'rd'
  ELSE 'th'
END AS Ordinal

एक्सेल के लिए:

=MID("thstndrdth",MIN(9,2*RIGHT(A1)*(MOD(A1-11,100)>2)+1),2)

अभिव्यक्ति (FALSE = 0) (MOD(A1-11,100)>2)को समाप्त करने के अलावा सभी संख्याओं के लिए TRUE (1 11,12,13) है। तो 2 * RIGHT(A1) * (MOD(A1-11,100)>2) +1)११/१२/१३ के लिए १ के रूप में समाप्त होता है, अन्यथा:
१ का मूल्यांकन ३
२ से ५,
३ से
: अन्य: ९
- और आवश्यक २ अक्षरों से होता है।"thstndrdth" उस स्थिति शुरू होने से होता है।

यदि आप वास्तव में इसे सीधे SQL में बदलना चाहते हैं, तो इसने मेरे लिए कुछ परीक्षण मानों के लिए काम किया:

DECLARE @n as int
SET @n=13
SELECT SubString(  'thstndrdth'
                 , (SELECT MIN(value) FROM
                     (SELECT 9 as value UNION
                      SELECT 1+ (2* (ABS(@n) % 10)  *  CASE WHEN ((ABS(@n)+89) % 100)>2 THEN 1 ELSE 0 END)
                     ) AS Mins
                   )
                 , 2
                )

0

यह कार्यान्वयन है dartऔर भाषा के अनुसार संशोधित किया जा सकता है।

String getOrdinalSuffix(int num){
    if (num.toString().endsWith("11")) return "th";
    if (num.toString().endsWith("12")) return "th";
    if (num.toString().endsWith("13")) return "th";
    if (num.toString().endsWith("1")) return "st";
    if (num.toString().endsWith("2")) return "nd";
    if (num.toString().endsWith("3")) return "rd";
    return "th";
}

0

जबकि यहाँ बहुत सारे अच्छे उत्तर हैं, मुझे लगता है कि एक और एक के लिए जगह है, इस बार पैटर्न मिलान के आधार पर, अगर किसी और चीज़ के लिए नहीं, तो कम से कम बहस योग्य पठनीयता के लिए

    public static string Ordinals1(this int number)
    {
        switch (number)
        {
            case int p when p % 100 == 11:
            case int q when q % 100 == 12:
            case int r when r % 100 == 13:
                return $"{number}th";
            case int p when p % 10 == 1:
                return $"{number}st";
            case int p when p % 10 == 2:
                return $"{number}nd";
            case int p when p % 10 == 3:
                return $"{number}rd";
            default:
                return $"{number}th";
        }
    }

और यह समाधान क्या खास बनाता है? इस तथ्य के अलावा और कुछ नहीं कि मैं विभिन्न अन्य समाधानों के लिए कुछ प्रदर्शन विचार जोड़ रहा हूं

स्पष्ट रूप से मुझे संदेह है कि प्रदर्शन वास्तव में इस विशेष परिदृश्य (जो वास्तव में लाखों की संख्या में अध्यादेशों की आवश्यकता है) के लिए मायने रखता है, लेकिन कम से कम कुछ तुलनाओं को ध्यान में रखा जाना चाहिए ...

संदर्भ के लिए 1 मिलियन आइटम (आपकी मिल अलग-अलग मशीन के चश्मे के आधार पर भिन्न हो सकते हैं)

पैटर्न मिलान और विभाजन के साथ (यह उत्तर)

~ 622 एमएस

पैटर्न मिलान और तार के साथ (यह उत्तर)

~ 1967 मि

दो स्विच और डिवीजनों (स्वीकृत उत्तर) के साथ

~ 637 मि

एक स्विच और डिवीजनों के साथ (दूसरा जवाब)

~ 725 मि

void Main()
{
    var timer = new Stopwatch();
    var numbers = Enumerable.Range(1, 1000000).ToList();

    // 1
    timer.Reset();
    timer.Start();
    var results1 = numbers.Select(p => p.Ordinals1()).ToList();
    timer.Stop();
    timer.Elapsed.TotalMilliseconds.Dump("with pattern matching and divisions");

    // 2
    timer.Reset();
    timer.Start();
    var results2 = numbers.Select(p => p.Ordinals2()).ToList();
    timer.Stop();
    timer.Elapsed.TotalMilliseconds.Dump("with pattern matching and strings");

    // 3
    timer.Reset();
    timer.Start();
    var results3 = numbers.Select(p => p.Ordinals3()).ToList();
    timer.Stop();
    timer.Elapsed.TotalMilliseconds.Dump("with two switches and divisons");

    // 4
    timer.Reset();
    timer.Start();
    var results4 = numbers.Select(p => p.Ordinals4()).ToList();
    timer.Stop();
    timer.Elapsed.TotalMilliseconds.Dump("with one switche and divisons");
}

public static class Extensions
{
    public static string Ordinals1(this int number)
    {
        switch (number)
        {
            case int p when p % 100 == 11:
            case int q when q % 100 == 12:
            case int r when r % 100 == 13:
                return $"{number}th";
            case int p when p % 10 == 1:
                return $"{number}st";
            case int p when p % 10 == 2:
                return $"{number}nd";
            case int p when p % 10 == 3:
                return $"{number}rd";
            default:
                return $"{number}th";
        }
    }

    public static string Ordinals2(this int number)
    {
        var text = number.ToString();
        switch (text)
        {
            case string p when p.EndsWith("11"):
                return $"{number}th";
            case string p when p.EndsWith("12"):
                return $"{number}th";
            case string p when p.EndsWith("13"):
                return $"{number}th";
            case string p when p.EndsWith("1"):
                return $"{number}st";
            case string p when p.EndsWith("2"):
                return $"{number}nd";
            case string p when p.EndsWith("3"):
                return $"{number}rd";
            default:
                return $"{number}th";
        }
    }

    public static string Ordinals3(this int number)
    {
        switch (number % 100)
        {
            case 11:
            case 12:
            case 13:
                return $"{number}th";
        }

        switch (number % 10)
        {
            case 1:
                return $"{number}st";
            case 2:
                return $"{number}nd";
            case 3:
                return $"{number}rd";
            default:
                return $"{number}th";
        }
    }

    public static string Ordinals4(this int number)
    {
        var ones = number % 10;
        var tens = Math.Floor(number / 10f) % 10;
        if (tens == 1)
        {
            return $"{number}th";
        }

        switch (ones)
        {
            case 1:
                return $"{number}th";
            case 2:
                return $"{number}nd";
            case 3:
                return $"{number}rd";
            default:
                return $"{number}th";
        }
    }
}

0

एक अन्य वन-लाइनर, लेकिन केवल रेक्सक्स इंडेक्सिंग द्वारा तुलना के बिना एक सरणी में परिणाम।

public static string GetOrdinalSuffix(int input)
{
    return new []{"th", "st", "nd", "rd"}[Convert.ToInt32("0" + Regex.Match(input.ToString(), "(?<!1)[1-3]$").Value)];
}

PowerShell संस्करण को आगे छोटा किया जा सकता है:

function ord($num) { return ('th','st','nd','rd')[[int]($num -match '(?<!1)[1-3]$') * $matches[0]] }

0

एक और 1 लाइनर।

public static string Ordinal(this int n)
{    
 return n + (new [] {"st","nd","rd" }.ElementAtOrDefault((((n + 90) % 100 - 10) % 10 - 1)) ?? "th");
}

-2

यहाँ DateTime एक्सटेंशन क्लास है। कॉपी, पेस्ट और आनंद लें

सार्वजनिक स्थैतिक वर्ग DateTimeExtensions {

    public static string ToStringWithOrdinal(this DateTime d)
    {
        var result = "";
        bool bReturn = false;            

        switch (d.Day % 100)
        {
            case 11:
            case 12:
            case 13:
                result = d.ToString("dd'th' MMMM yyyy");
                bReturn = true;
                break;
        }

        if (!bReturn)
        {
            switch (d.Day % 10)
            {
                case 1:
                    result = d.ToString("dd'st' MMMM yyyy");
                    break;
                case 2:
                    result = d.ToString("dd'nd' MMMM yyyy");
                    break;
                case 3:
                    result = d.ToString("dd'rd' MMMM yyyy");
                    break;
                default:
                    result = d.ToString("dd'th' MMMM yyyy");
                    break;
            }

        }

        if (result.StartsWith("0")) result = result.Substring(1);
        return result;
    }
}

परिणाम :

9 अक्टूबर 2014


आप डुप्लिकेट कर रहे हैं: ए) दिनांक प्रारूप स्ट्रिंग (एक्स 5) और बी) विधि के पूरे बाकी (जब संभावित उपयोग मामला उठता है (यदि यह पहले से ही नहीं है) कि गैर-प्रत्यय महीने के गैर-दिन के लिए आवश्यक है प्रयोजनों या एक अलग तारीख प्रारूप स्ट्रिंग के साथ महीने का एक दिन)। "OrdinalSuffix" विधि मैं 16:32 जवाब (कम से इयान वारबर्टन के अप्रैल 6 '17 से अवगत कराया सुझाव का प्रयोग करें stackoverflow.com/questions/20156/... )।
टॉम

-3

एक अन्य विकल्प जो मैंने अन्य सभी सुझावों के आधार पर इस्तेमाल किया, लेकिन इसके लिए किसी विशेष आवरण की आवश्यकता नहीं है:

    public static string DateSuffix(int day)
    {
        if (day == 11 | day == 12 | day == 13) return "th";
        Math.DivRem(day, 10, out day);
        switch (day)
        {
            case 1:
                return "st";
            case 2:
                return "nd";
            case 3:
                return "rd";
            default:
                return "th";
        }
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.