আমি যখন স্ট্রিংয়ের সংখ্যাসূচক হয়ে থাকি তখন মানের জন্য অ্যাকাউন্টিং করার সময় আমি স্ট্রিংগুলিকে বর্ণানুক্রমে কীভাবে বাছাই করব?


101

আমি স্ট্রিং সংখ্যার একটি অ্যারে বাছাই করার চেষ্টা করছি এবং আমি তাদের সংখ্যার অনুসারে বাছাই করতে চাই।

ধরা যে আমি int মধ্যে সংখ্যার রূপান্তর করতে পারবে না

কোডটি এখানে:

string[] things= new string[] { "105", "101", "102", "103", "90" };

foreach (var thing in things.OrderBy(x => x))
{
    Console.WriteLine(thing);
}

আউটপুট: 101, 102, 103, 105, 90

আমি চাই: 90, 101, 102, 103, 105

সম্পাদনা: আউটপুট 090, 101, 102 হতে পারে না ...

"আকার" এর পরিবর্তে "জিনিসগুলি" বলতে কোড নমুনা আপডেট করেছে। অ্যারে এমন কিছু হতে পারে:

string[] things= new string[] { "paul", "bob", "lauren", "007", "90" };

এর অর্থ এটি বর্ণমালা এবং সংখ্যা অনুসারে বাছাই করা দরকার:

007, 90, বব, লরেন, পল


8
আপনি কেন তাদের ইনটে রূপান্তর করতে পারবেন না?
Femaref

4
"আকার" কিছু "নাম" এর মতো হতে পারে। কোড নমুনা স্রেফ সরলীকৃত।
এসএফ।

4
সংখ্যার কোনওটি কি নেতিবাচক হবে? তারা সবাই কি পূর্ণসংখ্যা হবে? পূর্ণসংখ্যার পরিসীমা কত?
এরিক লিপার্ট

"জিনিস" যে কোনও ধরণের স্ট্রিং হতে পারে। আমি চাই কম্পিউটারটি অ-শিক্ষিত ব্যক্তির কাছে তালিকাকে যুক্তিযুক্তভাবে সাজানো হোক। নেতিবাচক সংখ্যাগুলি পোস্টের আগে হওয়া উচিত। স্ট্রিংয়ের দৈর্ঘ্যের ক্ষেত্রে এটি 100 টিরও বেশি অক্ষর হতে পারে।
এসএফ।

5
আপনি কত দূর যেতে চান? image10পরে আসা উচিত image2? Januaryআগে আসা উচিত February?
সুইভ

উত্তর:


104

অর্ডারবাইতে একটি কাস্টম তুলক পাস করুন। গণনাযোগ্য.আর্ডারবাই আপনাকে যে কোনও তুলনামূলক পছন্দ করতে দেয়।

এটি করার একটি উপায় এটি:

void Main()
{
    string[] things = new string[] { "paul", "bob", "lauren", "007", "90", "101"};

    foreach (var thing in things.OrderBy(x => x, new SemiNumericComparer()))
    {    
        Console.WriteLine(thing);
    }
}


public class SemiNumericComparer: IComparer<string>
{
    /// <summary>
    /// Method to determine if a string is a number
    /// </summary>
    /// <param name="value">String to test</param>
    /// <returns>True if numeric</returns>
    public static bool IsNumeric(string value)
    {
        return int.TryParse(value, out _);
    }

    /// <inheritdoc />
    public int Compare(string s1, string s2)
    {
        const int S1GreaterThanS2 = 1;
        const int S2GreaterThanS1 = -1;

        var IsNumeric1 = IsNumeric(s1);
        var IsNumeric2 = IsNumeric(s2);

        if (IsNumeric1 && IsNumeric2)
        {
            var i1 = Convert.ToInt32(s1);
            var i2 = Convert.ToInt32(s2);

            if (i1 > i2)
            {
                return S1GreaterThanS2;
            }

            if (i1 < i2)
            {
                return S2GreaterThanS1;
            }

            return 0;
        }

        if (IsNumeric1)
        {
            return S2GreaterThanS1;
        }

        if (IsNumeric2)
        {
            return S1GreaterThanS2;
        }

        return string.Compare(s1, s2, true, CultureInfo.InvariantCulture);
    }
}

4
প্রদত্ত ইনপুটটির জন্য, এটি পুনরাবৃত্তির জবাব হিসাবে একই ফলাফল তৈরি করে, যা প্যাডলফ্ট () জড়িত। আমি ধরে নিচ্ছি যে আপনার ইনপুটটি এই উদাহরণটি দেখানোর চেয়ে আসলে আরও জটিল, সেক্ষেত্রে একটি কাস্টম তুলনাকারী যাওয়ার উপায়।
জেফ পাউলসেন

চিয়ার্স এই সমাধানটি কার্যকর হয় এবং কার্যকরভাবে পড়ার সহজ এবং পরিষ্কার উপায় বলে মনে হয়। আমাকে দেখানোর জন্য +1 আপনি অর্ডারবাই :)
এসএফ-

17
IsNumericপদ্ধতি খারাপ, কোডিং চালিত একটি ব্যতিক্রম সবসময় খারাপ। int.TryParseপরিবর্তে ব্যবহার করুন। একটি বৃহত তালিকা সহ আপনার কোড চেষ্টা করুন এবং এটি চিরকালের জন্য লাগবে।
নিয়ান দের থাল

যদি এটি সহায়ক হয় তবে আমি এখানে এই সংস্করণে একটি এক্সটেনশন যুক্ত করেছি যা শব্দের সাথে বাছাইয়ের জন্য সমর্থন যোগ করে। আমার প্রয়োজনের জন্য, স্পেসে বিভাজন যথেষ্ট ছিল, এবং আমার মিশ্র ব্যবহারের শব্দগুলি সম্পর্কে উদ্বিগ্ন হওয়ার খুব দরকার ছিল না (উদাহরণস্বরূপ টেস্ট 12 বনাম টেস্ট 3),
matt.bungard

@ নিয়ানডারহল আমি নিশ্চিত যে আপনি কোনও ডিবাগিং করছেন বা আপনি যদি ব্যতিক্রমী অ্যাক্সেসটি অ্যাক্সেস করছেন তবে লুপটিতে কেবলমাত্র ধীর / খারাপ পরিচালনা করতে পারবেন ceptions
কেলি এলটন

92

শূন্যের সাথে একই দৈর্ঘ্যে প্যাড করুন:

int maxlen = sizes.Max(x => x.Length);
var result = sizes.OrderBy(x => x.PadLeft(maxlen, '0'));

সহজ সমাধানের জন্য +1, নিটপিকিং হবে (ইতিমধ্যে সম্পাদনায় সম্পন্ন হয়েছে, দুর্দান্ত)
মেরিনো Šimić

সুন্দর ধারণা তবে পরবর্তী ক্যাপচারটি হ'ল আমাকে এই মানগুলি ডিপ্লে করতে হবে তাই "90" "" 090 "
এসএফ

6
@ এসএফ: চেষ্টা করুন, আপনি ফলাফল পছন্দ করতে পারেন। মনে রাখবেন, অর্ডার কীটি অর্ডার করা জিনিস নয়। আমি যদি সর্বশেষ নামের সাথে গ্রাহকদের একটি তালিকা অর্ডার করতে বলেছিলাম, তবে আমি গ্রাহকদের একটি তালিকা পেয়েছি, শেষ নামগুলির একটি তালিকা নয়। যদি আপনি কোনও রূপান্তরিত স্ট্রিং দ্বারা স্ট্রিংয়ের তালিকার অর্ডার করতে বলেন তবে ফলাফলটি মূল স্ট্রিংগুলির ক্রমযুক্ত আদেশের তালিকা, রূপান্তরিত স্ট্রিংগুলির নয়।
এরিক লিপার্ট

এই কাজটি করতে আমাকে "মাপ = মাপ.অর্ডার বাই (...)" যুক্ত করতে হয়েছিল। এটি কি স্বাভাবিক বা উত্তরটি সম্পাদনা করা উচিত?
গর্বাবল

4
@ গোরগাবাল: সাধারণভাবে পুনরায় নির্ধারণ করা sizesহয় না হয় কাজ করে না, কারণ ফলাফলটি ভিন্ন ধরণের। উত্তরটি হ'ল হ্যান্ড-হ্যান্ডে, দ্বিতীয় পংক্তিতে ফলাফলটি একটি অভিব্যক্তি হিসাবে দেখায়, তবে এটি দিয়ে কিছু করা পাঠকের উপর নির্ভর করে। এটিকে আরও পরিষ্কার করার জন্য আমি আরেকটি পরিবর্তনশীল অ্যাসাইনমেন্ট যুক্ত করেছি।
পুনরাবৃত্তি

76

এবং, এটি সম্পর্কে ...

string[] sizes = new string[] { "105", "101", "102", "103", "90" };

var size = from x in sizes
           orderby x.Length, x
           select x;

foreach (var p in size)
{
    Console.WriteLine(p);
}

হেই, আমি সত্যিই এটি পছন্দ - খুব চালাক। দুঃখিত যদি আমি প্রাথমিক তথ্য
sf এর

4
এটি কেবলমাত্র আরও ভাল আইএমওর উপরে প্যাড বিকল্পের মতো।
dudeNumber4

4
var আকার = আকার। অর্ডারবি (x => x. দৈর্ঘ্য) .তখনই (x => x);
ফিলিপ ডেভিস

4
কিন্তু এই ভালো বর্ণানুক্রমিক স্ট্রিং মিশ্রিত করা হবে: "b", "ab", "101", "103", "bob", "abcd"
এন্ড্রু

72

মান একটি স্ট্রিং

List = List.OrderBy(c => c.Value.Length).ThenBy(c => c.Value).ToList();

কাজ


4
এই উত্তরটি আমার প্রিয়।
LacOniC

4
ধন্যবাদ আমি কেবল আবিষ্কার করেছি যা "থাটারবাই" পদ্ধতিটি থেকে বেরিয়ে আসে।
ganchito55

এটি আমার ব্যবহারের ক্ষেত্রে দুর্দান্ত কাজ করে, যেখানে ইনপুটটি নতুন ফর্ম্যাটে রয়েছেstring[] { "Object 1", "Object 9", "Object 14" }
থেলেম

4
এটি সেরা উত্তর। এটি কাজ করে এবং একটি ভাল শেখার। ধন্যবাদ !!
জুলাইআরডিনারি

4
কিন্তু এই ভালো বর্ণানুক্রমিক স্ট্রিং মিশ্রিত করা হবে: "b", "ab", "101", "103", "bob", "abcd"
অ্যান্ড্রু

14

উইন্ডোগুলিতে একটি নেটিভ ফাংশন রয়েছে StrCmpLogicalWযা অক্ষরের পরিবর্তে সংখ্যা হিসাবে স্ট্রিং সংখ্যার সাথে তুলনা করবে। এমন একটি তুলনাকারী তৈরি করা সহজ যা সেই ফাংশনে কল করে এবং তার তুলনার জন্য এটি ব্যবহার করে।

public class StrCmpLogicalComparer : Comparer<string>
{
    [DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
    private static extern int StrCmpLogicalW(string x, string y);

    public override int Compare(string x, string y)
    {
        return StrCmpLogicalW(x, y);
    }
}

এমনকি এটি স্ট্রিংগুলিতেও কাজ করে যা পাঠ্য এবং সংখ্যা উভয়ই রয়েছে। এখানে একটি উদাহরণ প্রোগ্রাম যা ডিফল্ট সাজানোর মধ্যে diffrence দেখাবে হয় StrCmpLogicalWসাজানোর

class Program
{
    static void Main()
    {
        List<string> items = new List<string>()
        {
            "Example1.txt", "Example2.txt", "Example3.txt", "Example4.txt", "Example5.txt", "Example6.txt", "Example7.txt", "Example8.txt", "Example9.txt", "Example10.txt",
            "Example11.txt", "Example12.txt", "Example13.txt", "Example14.txt", "Example15.txt", "Example16.txt", "Example17.txt", "Example18.txt", "Example19.txt", "Example20.txt"
        };

        items.Sort();

        foreach (var item in items)
        {
            Console.WriteLine(item);
        }

        Console.WriteLine();

        items.Sort(new StrCmpLogicalComparer());

        foreach (var item in items)
        {
            Console.WriteLine(item);
        }
        Console.ReadLine();
    }
}

যা ফলাফল

Example1.txt
Example10.txt
Example11.txt
Example12.txt
Example13.txt
Example14.txt
Example15.txt
Example16.txt
Example17.txt
Example18.txt
Example19.txt
Example2.txt
Example20.txt
Example3.txt
Example4.txt
Example5.txt
Example6.txt
Example7.txt
Example8.txt
Example9.txt

Example1.txt
Example2.txt
Example3.txt
Example4.txt
Example5.txt
Example6.txt
Example7.txt
Example8.txt
Example9.txt
Example10.txt
Example11.txt
Example12.txt
Example13.txt
Example14.txt
Example15.txt
Example16.txt
Example17.txt
Example18.txt
Example19.txt
Example20.txt

আমি আশা করি সি #
কাইল ডেলানী

এটি নিখুঁত হত তবে দুর্ভাগ্যক্রমে এটি নেতিবাচক সংখ্যাগুলি পরিচালনা করে না। -1 0 10 2যেমন অনুসারে বাছাই করা হয়0 -1 2 10
nphx

5

এটা চেষ্টা কর

sizes.OrderBy(x => Convert.ToInt32(x)).ToList<string>();

দ্রষ্টব্য: যখন সমস্ত স্ট্রিং ইন্টে রূপান্তরিত হয় তখন এটি সহায়ক


4
এই কিন্ডা স্ট্রিংকে একটি ইনটেমে রূপান্তর করে।
Femaref


"লিনকিউ থেকে এসকিউএল" এর জন্য ToList()আগে =>sizes.ToList().OrderBy(x => Convert.ToInt32(x))
এ। মোরেল

5

আমি মনে করি এটি স্ট্রিংয়ের কিছু সংখ্যাসূচক থাকলে এটি আরও ভাল হবে। আশা করি এটি সাহায্য করবে।

পিএস: আমি পারফরম্যান্স বা জটিল স্ট্রিংয়ের মান সম্পর্কে নিশ্চিত নই তবে এটি ভালো কিছু নিয়ে কাজ করেছে:

আর্কাইভ
আর্কাইভ 1
আর্কাইভ 2
আর্কাইভ 3
...
আর্কাইভ 20
আর্কাইভ 21

public class SemiNumericComparer : IComparer<string>
{
    public int Compare(string s1, string s2)
    {
        int s1r, s2r;
        var s1n = IsNumeric(s1, out s1r);
        var s2n = IsNumeric(s2, out s2r);

        if (s1n && s2n) return s1r - s2r;
        else if (s1n) return -1;
        else if (s2n) return 1;

        var num1 = Regex.Match(s1, @"\d+$");
        var num2 = Regex.Match(s2, @"\d+$");

        var onlyString1 = s1.Remove(num1.Index, num1.Length);
        var onlyString2 = s2.Remove(num2.Index, num2.Length);

        if (onlyString1 == onlyString2)
        {
            if (num1.Success && num2.Success) return Convert.ToInt32(num1.Value) - Convert.ToInt32(num2.Value);
            else if (num1.Success) return 1;
            else if (num2.Success) return -1;
        }

        return string.Compare(s1, s2, true);
    }

    public bool IsNumeric(string value, out int result)
    {
        return int.TryParse(value, out result);
    }
}

ঠিক আমি খুঁজছেন ছিল কি. ধন্যবাদ!
ক্লুজেরাম

4

আপনি বলছেন যে আপনি সংখ্যাগুলিকে ইন্টিতে রূপান্তর করতে পারবেন না কারণ অ্যারেতে এমন উপাদান থাকতে পারে যা ইন্টে রূপান্তর করা যায় না, তবে চেষ্টা করার কোনও ক্ষতি নেই:

string[] things = new string[] { "105", "101", "102", "103", "90", "paul", "bob", "lauren", "007", "90" };
Array.Sort(things, CompareThings);

foreach (var thing in things)
    Debug.WriteLine(thing);

তারপরে এর সাথে তুলনা করুন:

private static int CompareThings(string x, string y)
{
    int intX, intY;
    if (int.TryParse(x, out intX) && int.TryParse(y, out intY))
        return intX.CompareTo(intY);

    return x.CompareTo(y);
}

আউটপুট: 007, 90, 90, 101, 102, 103, 105, বব, লরেন, পল


বিটিডব্লিউ, আমি সরলতার জন্য অ্যারে ব্যবহার করেছি S বাছাই করেছিলাম, তবে আপনি একই আইকোপ্যামারটিতে লজিকটি ব্যবহার করতে পারেন এবং অর্ডারবাই ব্যবহার করতে পারেন।
উলফ ক্রিস্টিয়েনসেন

এই সমাধানটি আইসিম্পারার (আমার মতামত) ব্যবহার করে দ্রুত বলে মনে হচ্ছে। 15000 ফলাফল এবং আমি এটির দ্বিতীয় পার্থক্য সম্পর্কে ফলন অনুভব করি।
জেসন ফোগলিয়া

3

এটি একটি অদ্ভুত অনুরোধ বলে মনে হচ্ছে এবং এটি একটি অদ্ভুত সমাধানের দাবি রাখে:

string[] sizes = new string[] { "105", "101", "102", "103", "90" };

foreach (var size in sizes.OrderBy(x => {
    double sum = 0;
    int position = 0;
    foreach (char c in x.ToCharArray().Reverse()) {
        sum += (c - 48) * (int)(Math.Pow(10,position));
        position++;
    }
    return sum;
}))

{
    Console.WriteLine(size);
}

আমি অবশ্যই 0x30 বলতে চাইছি। এছাড়াও, অ্যারেটিতে এখনও একটি অ-সংখ্যাযুক্ত স্ট্রিং থাকতে পারে, যার জন্য সমাধানটি আকর্ষণীয় ফলাফল আনবে produce
Femaref

এবং মনে রাখবেন যে -৪৮ বা একেবারে কোনও পরিবর্তন হয় না, আমরা সরাসরি চরের পূর্ণসংখ্যা মানটি ব্যবহার করতে পারি, সুতরাং আপনাকে বিরক্ত করে যদি -৪৮ সরিয়ে ফেলুন ...
মেরিনো Šমিć

চরটির মান 0x30, আপনি যদি এটি ইনটকে রূপান্তর করেন তবে এটি 0x30 হবে, যা সংখ্যা 0 নয়
ফেমারেফ

পূর্ণসংখ্যায় রূপান্তরিত হ'ল একমাত্র জিনিসটি হ'ল ম্যাথ থেকে ফেরত আসা ডাব্লু owউউ
মেরিনো

এটি যদি শূন্য হয় বা না তা বিবেচনা করে না, ডিক্যাডিক সিস্টেম এটির যত্ন নেয়, এটি Đ আপনি যদি চান তবে কেবল একটি বিষয় যা সংখ্যাগুলি চরিত্রের সংখ্যায় আরোহণের আদেশে রয়েছে এবং এটি কম 10 এর চেয়ে বেশি
মেরিনো Šimić

3

এই সাইটটি বর্ণানুক্রমিক বাছাই করা নিয়ে আলোচনা করে এবং একটি ASCII সংজ্ঞার পরিবর্তে লজিকাল অর্থে সংখ্যার বাছাই করবে। এটি চারপাশের বর্ণমালাটিকেও বিবেচনা করে:

http://www.dotnetperls.com/alphanumeric-sorting

উদাহরণ:

  • সি: / টেস্টবি / 333.jpg
  • 11
  • সি: / টেস্টবি / .৩.জেপিজি
  • সি: / টেস্টএ / 111.jpg
  • 111F
  • সি: / টেস্টা 11/jpg
  • সি: / টেস্টএ / ১.জেপিজি
  • 111 ডি
  • 22
  • 111 জেড
  • সি: / টেস্টবি/0৩.জেপিজি

  • 11
  • 22
  • 111 ডি
  • 111F
  • 111 জেড
  • সি: / টেস্টএ / ১.জেপিজি
  • সি: / টেস্টা 11/jpg
  • সি: / টেস্টএ / 111.jpg
  • সি: / টেস্টবি/0৩.জেপিজি
  • সি: / টেস্টবি / .৩.জেপিজি
  • সি: / টেস্টবি / 333.jpg

কোডটি নিম্নরূপ:

class Program
{
    static void Main(string[] args)
    {
        var arr = new string[]
        {
           "C:/TestB/333.jpg",
           "11",
           "C:/TestB/33.jpg",
           "1",
           "C:/TestA/111.jpg",
           "111F",
           "C:/TestA/11.jpg",
           "2",
           "C:/TestA/1.jpg",
           "111D",
           "22",
           "111Z",
           "C:/TestB/03.jpg"
        };
        Array.Sort(arr, new AlphaNumericComparer());
        foreach(var e in arr) {
            Console.WriteLine(e);
        }
    }
}

public class AlphaNumericComparer : IComparer
{
    public int Compare(object x, object y)
    {
        string s1 = x as string;
        if (s1 == null)
        {
            return 0;
        }
        string s2 = y as string;
        if (s2 == null)
        {
            return 0;
        }

        int len1 = s1.Length;
        int len2 = s2.Length;
        int marker1 = 0;
        int marker2 = 0;

        // Walk through two the strings with two markers.
        while (marker1 < len1 && marker2 < len2)
        {
            char ch1 = s1[marker1];
            char ch2 = s2[marker2];

            // Some buffers we can build up characters in for each chunk.
            char[] space1 = new char[len1];
            int loc1 = 0;
            char[] space2 = new char[len2];
            int loc2 = 0;

            // Walk through all following characters that are digits or
            // characters in BOTH strings starting at the appropriate marker.
            // Collect char arrays.
            do
            {
                space1[loc1++] = ch1;
                marker1++;

                if (marker1 < len1)
                {
                    ch1 = s1[marker1];
                }
                else
                {
                    break;
                }
            } while (char.IsDigit(ch1) == char.IsDigit(space1[0]));

            do
            {
                space2[loc2++] = ch2;
                marker2++;

                if (marker2 < len2)
                {
                    ch2 = s2[marker2];
                }
                else
                {
                    break;
                }
            } while (char.IsDigit(ch2) == char.IsDigit(space2[0]));

            // If we have collected numbers, compare them numerically.
            // Otherwise, if we have strings, compare them alphabetically.
            string str1 = new string(space1);
            string str2 = new string(space2);

            int result;

            if (char.IsDigit(space1[0]) && char.IsDigit(space2[0]))
            {
                int thisNumericChunk = int.Parse(str1);
                int thatNumericChunk = int.Parse(str2);
                result = thisNumericChunk.CompareTo(thatNumericChunk);
            }
            else
            {
                result = str1.CompareTo(str2);
            }

            if (result != 0)
            {
                return result;
            }
        }
        return len1 - len2;
    }
}

2

জেফ পলসেন প্রদত্ত উত্তরটি সঠিক তবে এর থেকে এটি Comprarerআরও সরল করা যেতে পারে:

public class SemiNumericComparer: IComparer<string>
{
    public int Compare(string s1, string s2)
    {
        if (IsNumeric(s1) && IsNumeric(s2))
          return Convert.ToInt32(s1) - Convert.ToInt32(s2)

        if (IsNumeric(s1) && !IsNumeric(s2))
            return -1;

        if (!IsNumeric(s1) && IsNumeric(s2))
            return 1;

        return string.Compare(s1, s2, true);
    }

    public static bool IsNumeric(object value)
    {
        int result;
        return Int32.TryParse(value, out result);
    }
}

Comparerফলাফলটি বড়, ছোট বা শূন্যের সমান হলে ফলাফলের জন্য যা পরীক্ষা করা হয় তা কেবলমাত্র এটিই কাজ করে । একটি সহজেই অন্যের কাছ থেকে মানগুলি বিয়োগ করতে পারে এবং ফেরতের মানগুলি হ্যান্ডেল করতে হয় না।

এছাড়াও IsNumericপদ্ধতিটিতে একটি- tryব্লক ব্যবহার করা উচিত নয় এবং এতে উপকৃত হতে পারে TryParse

এবং যারা নিশ্চিত নন তাদের জন্য: এই তুলনাটি মানগুলি বাছাই করবে যাতে অ-সংখ্যাগত মান সর্বদা তালিকার শেষে যুক্ত হয়। যদি কেউ তাদের শুরুতে চায় তবে দ্বিতীয় এবং তৃতীয় ifব্লকটি অদলবদল করতে হবে।


ট্রাই পার্সে পদ্ধতিটি কল করার সাথে সাথে সম্ভবত কিছু ওভারহেড রয়েছে, আমি প্রথমে এস 1 এবং এস 2 এর জন্য ইসনুমিক মানগুলিকে প্রথমে বুলিয়ান মানগুলিতে সংরক্ষণ করব এবং পরিবর্তে এর সাথে তুলনা করব। এইভাবে তারা একাধিকবার মূল্যায়ন করা হয় না।
অপ্টাভিয়াস

1

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

string[] things= new string[] { "105", "101", "102", "103", "90" };

int tmpNumber;

foreach (var thing in (things.Where(xx => int.TryParse(xx, out tmpNumber)).OrderBy(xx =>     int.Parse(xx))).Concat(things.Where(xx => !int.TryParse(xx, out tmpNumber)).OrderBy(xx => xx)))
{
    Console.WriteLine(thing);
}

1
public class NaturalSort: IComparer<string>
{
          [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
          public static extern int StrCmpLogicalW(string x, string y);

          public int Compare(string x, string y)
          {
                 return StrCmpLogicalW(x, y);
          }
}

arr = arr.OrderBy (x => x, নতুন NaturalSort ())। ToArray ();

আমার যে কারণটির প্রয়োজন ছিল তা হ'ল একটি ডিরেক্টরিতে ফাইল করা যাঁর ফাইল নামগুলি একটি নম্বর দিয়ে শুরু হয়েছিল:

public static FileInfo[] GetFiles(string path)
{
  return new DirectoryInfo(path).GetFiles()
                                .OrderBy(x => x.Name, new NaturalSort())
                                .ToArray();
}

0
Try this out..  



  string[] things = new string[] { "paul", "bob", "lauren", "007", "90", "-10" };

        List<int> num = new List<int>();
        List<string> str = new List<string>();
        for (int i = 0; i < things.Count(); i++)
        {

            int result;
            if (int.TryParse(things[i], out result))
            {
                num.Add(result);
            }
            else
            {
                str.Add(things[i]);
            }


        }

এখন তালিকাগুলি বাছাই করুন এবং সেগুলি আবার মার্জ করুন ...

        var strsort = from s in str
                      orderby s.Length
                      select s;

        var numsort = from n in num
                     orderby n
                     select n;

        for (int i = 0; i < things.Count(); i++)
        {

         if(i < numsort.Count())
             things[i] = numsort.ElementAt(i).ToString();
             else
             things[i] = strsort.ElementAt(i - numsort.Count());               
               }

আমি এই আকর্ষণীয় প্রশ্নে অবদান দেওয়ার চেষ্টা করেছি ...


0

আমার পছন্দসই সমাধান (যদি সমস্ত স্ট্রিং কেবল সংখ্যাসূচক হয়):

// Order by numerical order: (Assertion: all things are numeric strings only) 
foreach (var thing in things.OrderBy(int.Parse))
{
    Console.Writeline(thing);
}

0
public class Test
{
    public void TestMethod()
    {
        List<string> buyersList = new List<string>() { "5", "10", "1", "str", "3", "string" };
        List<string> soretedBuyersList = null;

        soretedBuyersList = new List<string>(SortedList(buyersList));
    }

    public List<string> SortedList(List<string> unsoredList)
    {
        return unsoredList.OrderBy(o => o, new SortNumericComparer()).ToList();
    }
}

   public class SortNumericComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        int xInt = 0;
        int yInt = 0;
        int result = -1;

        if (!int.TryParse(x, out xInt))
        {
            result = 1;
        }

        if(int.TryParse(y, out yInt))
        {
            if(result == -1)
            {
                result = xInt - yInt;
            }
        }
        else if(result == 1)
        {
             result = string.Compare(x, y, true);
        }

        return result;
    }
}

আপনি আপনার কোড ব্যাখ্যা করতে পারেন ? কেবল কোডের উত্তরগুলি মুছতে দায়বদ্ধ।
ওয়াই হা লি 17

জেফ পলসেন পোস্ট আমাকে আমার সরিংয়ের সমস্যাটি সমাধান করতে আইকম্পার <স্ট্রিং> প্রয়োগ করতে সহায়তা করেছিল। ।
কুমার

0

জেফ পলসেন উত্তরটি প্রসারিত করছেন। আমি নিশ্চিত করতে চেয়েছিলাম যে স্ট্রিংগুলিতে কতগুলি সংখ্যা বা চর গ্রুপ ছিল তা বিবেচ্য নয়:

public class SemiNumericComparer : IComparer<string>
{
    public int Compare(string s1, string s2)
    {
        if (int.TryParse(s1, out var i1) && int.TryParse(s2, out var i2))
        {
            if (i1 > i2)
            {
                return 1;
            }

            if (i1 < i2)
            {
                return -1;
            }

            if (i1 == i2)
            {
                return 0;
            }
        }

        var text1 = SplitCharsAndNums(s1);
        var text2 = SplitCharsAndNums(s2);

        if (text1.Length > 1 && text2.Length > 1)
        {

            for (var i = 0; i < Math.Max(text1.Length, text2.Length); i++)
            {

                if (text1[i] != null && text2[i] != null)
                {
                    var pos = Compare(text1[i], text2[i]);
                    if (pos != 0)
                    {
                        return pos;
                    }
                }
                else
                {
                    //text1[i] is null there for the string is shorter and comes before a longer string.
                    if (text1[i] == null)
                    {
                        return -1;
                    }
                    if (text2[i] == null)
                    {
                        return 1;
                    }
                }
            }
        }

        return string.Compare(s1, s2, true);
    }

    private string[] SplitCharsAndNums(string text)
    {
        var sb = new StringBuilder();
        for (var i = 0; i < text.Length - 1; i++)
        {
            if ((!char.IsDigit(text[i]) && char.IsDigit(text[i + 1])) ||
                (char.IsDigit(text[i]) && !char.IsDigit(text[i + 1])))
            {
                sb.Append(text[i]);
                sb.Append(" ");
            }
            else
            {
                sb.Append(text[i]);
            }
        }

        sb.Append(text[text.Length - 1]);

        return sb.ToString().Split(' ');
    }
}

আমি ফাইলের নাম নিয়ে কাজ করার জন্য সংশোধন করার পরে একটি এসও পৃষ্ঠা থেকে স্প্লিটচারসঅ্যান্ডনুমসও নিয়েছি ।


-1

যদিও এটি একটি পুরানো প্রশ্ন, আমি একটি সমাধান দিতে চাই:

string[] things= new string[] { "105", "101", "102", "103", "90" };

foreach (var thing in things.OrderBy(x => Int32.Parse(x) )
{
    Console.WriteLine(thing);
}

ওহহ বেশ সহজ? : ডি


-1
namespace X
{
    public class Utils
    {
        public class StrCmpLogicalComparer : IComparer<Projects.Sample>
        {
            [DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
            private static extern int StrCmpLogicalW(string x, string y);


            public int Compare(Projects.Sample x, Projects.Sample y)
            {
                string[] ls1 = x.sample_name.Split("_");
                string[] ls2 = y.sample_name.Split("_");
                string s1 = ls1[0];
                string s2 = ls2[0];
                return StrCmpLogicalW(s1, s2);
            }
        }

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