1

「int.int.int」形式の値を持つ配列があります

String[] tab = [ '100.2.0' , '5.7.4' , '7.6.1' , '5.6.4' ]

この配列を最初の番号でソートし、最初のソートの結果を2番目の番号でソートしたまま、最初の値でソートした配列を保持し、3番目の番号で同じことを行います。期待される結果:

[「5.6.4」、「5.7.4」、「7.6.1」、「100.2.0」]

最も簡単な解決策は、補助配列を作成して for ループを使用することですが、もっと簡単にできるかどうか疑問に思っています。Groovyソートも使用しようとしました

tab.sort { it -~ /\./ }

区切り記号を削除し、要素を整数のように並べ替えましたが、たとえばそのような値では機能しませんでした

[ '2.12.1' , '10.5.2' , '5.2.3' ]

出力は

[ '5.2.3' , '10.5.2' , '2.12.1' ]

新しい配列を作成して元の配列で3回繰り返すのではなく、簡単な方法で並べ替える方法はありますか?

4

5 に答える 5

0

アイデアは、各文字列を整数のタプルに変換することです (たとえば、名前を付けましょうNumberInfo)。つまり、"100.2.0" => { 100, 2, 0 } です。これは、整数表現が比較を実行するのに役立つためです (比較はアイテムを並べ替えます)。

したがって、 を に変換した後、List<String>List<NumberInfo>ソートList<NumberInfo>できます。

「タプル」:

class NumberInfo {
    private int a;
    private int b;
    private int c;

    private NumberInfo(int a, int b, int c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }

    int getA() {
        return a;
    }

    int getB() {
        return b;
    }

    int getC() {
        return c;
    }

    public static NumberInfo fromString(String s) {
        String[] itemComponents = s.split("[.]");
        if (itemComponents.length != 3) {
            throw new IllegalArgumentException("Three comma delimited components expected");
        }

        int a = Integer.parseInt(itemComponents[0]);
        int b = Integer.parseInt(itemComponents[1]);
        int c = Integer.parseInt(itemComponents[2]);

        NumberInfo numberInfo = new NumberInfo(a, b, c);
        return numberInfo;
    }

    @Override
    public String toString() {
        return a + "." + b + "." + c;
    }
}

タプルコンパレータ:

class NumberInfoComparator implements Comparator<NumberInfo> {
    @Override
    public int compare(NumberInfo o1, NumberInfo o2) {
        int result = Integer.compare(o1.getA(), o2.getA());
        if (result != 0)
            return result;

        result = Integer.compare(o1.getB(), o2.getB());
        if (result != 0) {
            return result;
        }

        result = Integer.compare(o1.getC(), o2.getC());
        return result;
    }
}

主な方法:

public static void main(String[] args) {
    String[] tab = { "100.2.0" , "5.7.4" , "7.6.1" , "5.6.4" };

    ArrayList<NumberInfo> numberInfoList = new ArrayList<NumberInfo>();
    for (String item : tab) {
        NumberInfo numberInfo = NumberInfo.fromString(item);
        numberInfoList.add(numberInfo);
    }

    NumberInfoComparator numberInfoComparator = new NumberInfoComparator();
    Collections.sort(numberInfoList, numberInfoComparator);

    for (NumberInfo numberInfo : numberInfoList) {
        System.out.println(numberInfo);
    }
}
于 2013-09-18T12:50:03.980 に答える
0

あなたはこれを行うことができます:

tab.sort { a, b -> [ a, b ]*.tokenize( '.' )*.
                           collect { it.toInteger() }
                           .transpose()
                           .findResult { x, y -> x <=> y ?: null } }

または(おそらくよりきちんとした)

tab.sort { a, b ->
    [ a, b ]*.tokenize( '.' )
             .transpose()
             .findResult { x, y ->
                  x.toInteger() <=> y.toInteger() ?: null
              }
}

または、バージョン番号が異なる数の整数になる可能性がある場合 (つまり1.6、 、1.7.43.3):

tab.sort { a, b ->
    [ a, b ]*.tokenize( '.' ).with { u, v ->
        [ u, v ].transpose().findResult { x, y ->
             x.toInteger() <=> y.toInteger() ?: null
        } ?: u.size() <=> v.size()
    }
}

または、カスタムコンパレータを使用してください;-)

于 2013-09-18T12:07:15.427 に答える