4

次のような CSV データがあります。

番号;バージョン
1;AA.1
1;A01.1
1;A01.2
1;Z.7

ここでは、次のように Version 列を降順に並べ替える必要があります。

番号;バージョン
1;AA.1
1;Z.7
1;A01.2
1;A01.1

したがって、Z.7 エントリは AA.1 の後に来るはずです。基本的に、降順ソートは次のように行う必要があります。

ソートされたバージョン:

BB
AA
Z
C
B
A

http://www.DaveKoelle.comで説明されている Alphanum アルゴリズムとhttp://www.codeproject.com/Articles/22517/Natural-Sort-Comparerの Natural Sort Comparer を 既に試しました。上記の並べ替えを除いて、私が望むすべてのことを行います。

4

1 に答える 1

3

そのため、CSV ファイルに従っていくつかのカスタム ロジックを並べ替える必要があるようです。これを実行するIComparer<string>には、クラスに実装Compareし、要件に基づいてメソッドを実装する必要があります。あなたの場合、最初に文字列をアルファベット部分と数値部分の2つの部分に分割し(正規表現を使用)、次に文字列を比較し、両方が同じ場合は数値部分を比較し、それに応じて値を返す必要があります。

その後、このComparerクラスを使用してそれらを並べ替えることができます。

アップデート

コードサンプル

public class CustomStringComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        int? result;
        if (AnyParamIsNull(x, y, out result))
        {
            return result.Value;
        }

        string x1, y1;
        double x2, y2;
        SplitInput(x, out x1, out x2);
        SplitInput(y, out y1, out y2);
        if (x1.Length == y1.Length)
        {
            result = string.Compare(x1, y1);
            if (result.Value == 0)
            {

                if (x2 < y2)
                {
                    return -1;
                }
                else if (x2 > y2)
                {
                    return 1;
                }
                else
                {
                    return 0;
                }


            }
            else
            {
                return result.Value;
            }
        }
        else
        {
            //To make AA before Z when desending
            return x1.Length - y1.Length;
        }

    }

    private bool SplitInput(string input, out string alphabets, out double number)
    {
        Regex regex = new Regex(@"\d*[.]?\d+");
        Match match = regex.Match(input);
        if (match.Success)
        {
            number = double.Parse(match.Value, CultureInfo.InvariantCulture);
            alphabets = input.Replace(match.Value, "");
            return true;
        }
        else
        {
            throw new ArgumentException("Input string is not of correct format", input);
        }
    }


    private bool AnyParamIsNull(string x, string y, out int? result)
    {
        result = null;
        if (x == null)
        {
            if (y == null)
            {
                // If x is null and y is null, they're 
                // equal.  
                result = 0;
                return true;
            }
            else
            {
                // If x is null and y is not null, y 
                // is greater.  
                result = -1;
                return true;
            }
        }
        else
        {
            // If x is not null... 
            // 
            if (y == null)
            // ...and y is null, x is greater.
            {
                result = 1;
                return true;
            }
        }
        return false;
    }
}

この比較ツールを使用するには

        List<string> input = new List<string>()
        {
            "AA.1",
            "A01.1",
            "A01.2",
            "Z.7"
        };

        input.Sort(new CustomStringComparer());
        //To sort decending
        input.Reverse();

注意: 上記のコードは正しいだけで、それ以外ではないことを証明しました。期待どおりに動作しない可能性があるいくつかのエッジケースが存在する可能性があります

于 2012-10-22T05:29:12.720 に答える