1

並べ替える必要のあるオブジェクトを含む配列があり、各配列項目の3つの特定の値に基づいて重複を削除します。現在、2つのループ(ネストされていない)を使用しています。1つは並べ替え、もう1つはアイテムの削除です。並べ替えなどで重複を削除する方法はありますか?何千ものアイテムの場合、次のコードは非常に遅く、より速い方法があるかどうか疑問に思っています。

var list = [
    {a: "Somename", b: "b", c: 10},
    {a: "Anothername", b: "a", c: 12},
    // and so on
];
function sortList(list) {
    // Sort the list based on the 3 specific values
    list = list.sort(function(a,b) {
        a.a = a.a.toLowerCase();
        b.a = b.a.toLowerCase();
        if (a.a < b.a) return -1;
        if (a.a > b.a) return 1;

        a.b = a.b.toLowerCase();
        b.b = b.b.toLowerCase();
        if (a.b < b.b) return -1;
        if (a.b > b.b) return 1;

        if (a.c < b.c) return -1;
        if (a.c > b.c) return 1;

        return 0;
    });

    // Loop through removing duplicates
    for (var a,b,i=list.length-1; i > 0; i--) {
        a = list[i];
        a.a = a.a.toLowerCase();
        a.b = a.b.toLowerCase();

        b = list[i-1];
        b.a = b.a.toLowerCase();
        b.b = b.b.toLowerCase();

        if (a.a===b.a && a.b===b.b && a.c===b.c) list.splice(i-1,1);
    }

    return list;
}
list = sortList(list);

jQueryの回答、または別のライブラリの使用を示唆する回答はしないでください。これほど単純なことをするためにライブラリをインポートするのは少しやり過ぎのようです。

4

2 に答える 2

0

2番目のループで使用する代わりにsplice、一意の値を新しい配列に配置するだけです。したがって、各反復で、既存の配列を使用する代わりにsplice、新しい配列に値を追加するだけです。pushよりもはるかに高速ですsplice。例えば:

var newList = [];
if (list) {
    newList.push(list[0];
    for (var a,b,i=1; i < list.length; i++) {
        a = list[i];
        a.a = a.a.toLowerCase();
        a.b = a.b.toLowerCase();

        b = list[i-1];
        b.a = b.a.toLowerCase();
        b.b = b.b.toLowerCase();

        if (a.a!==b.a || a.b!==b.b && a.c!==b.c) {
            newList.push(a);
        }
    }
}
于 2012-08-17T09:38:57.427 に答える
0

探し回った後、私は自分の答えを思いついた。引き続き2つのループを使用しますが、これは、並べ替えてから重複を削除するよりもはるかに高速であり、並べ替え中に重複を追跡するよりも一貫性があります。基本的に、配列をループして、重複を並べ替え/削除するプロパティ値('key')の連結を使用して、各アイテムをオブジェクトに保存します。キーがすでに保存されている場合は、それが重複していることがわかっているので、次のキーに進むことができます。それ以外の場合は、アイテムを新しい配列に追加します。重複が削除されたら、配列を並べ替えて返します。

function sortList(list){
    // Since the 3 properties I'm sorting by can be converted to string I can loop
    // through the specified array, creating 'keys' by concating those property values
    // and adding those 'keys' to a temporary object. If the 'key' is present in the
    // temporary object, I know it's a duplicate in the array and can ignore it.
    // Otherwise I know it's not a duplicate and add it to a new array
    for (var a=0,b=list.length,item,key="",dupObj={},nList=[]; a<b; a++) {
        item=list[a];
        key=item.a.toLowerCase()+"_"+item.b.toLowerCase()+"_"+item.c;
        if(!dupObj[key]) {
            dupObj[key]=true;
            nList.push(item);
        }
    }

    // Now that we have an array without duplicates we can sort the array:
    nList.sort(function(a,b) {
        if ((a.a = a.a.toLowerCase()) < (b.a = b.a.toLowerCase()) return -1;
        if (a.a > b.a) return 1;

        if ((a.b = a.b.toLowerCase()) < (b.b = b.b.toLowerCase())) return -1;
        if (a.b > b.b) return 1;

        if (a.c < b.c) return -1;
        if (a.c > b.c) return 1;

        return 0;
    });

    // return the new list
    return nList;
}
var list = [
    {a: "Somename", b: "b", c: 10},
    {a: "Anothername", b: "a", c: 12},
    // and so on
];
list = sortList(list);
于 2012-08-17T10:52:21.330 に答える