1

array.sort を使用して、オブジェクトの配列を並べ替えています。

自分で比較する以外に、これらのオブジェクトの順序が変更されたかどうかを判断する方法はありますか? 組み込みの JS 関数はありますか? 少なくとも 1 つの変更があったというだけで、変更の数を知る必要はありません。

アップデート:

カスタム オブジェクトを並べ替えています。

[
 { 'value' : 5, 'name' : 'foo'},
 { 'value' : 3, 'name' : 'bar'},
 { 'value' : 10, 'name' : 'js'}
]

更新 2:

オブジェクトを生成するときにカスタム プロパティ 'order' を追加し、.sort の後で 'order' が連続しているかどうかを確認することを検討しています。より速い/より良い方法はありますか?

4

8 に答える 8

3

あなたが求めていることをするものは何も組み込まれていません。単純な配列の場合は、join/toString() を使用して、2 つの最終的な文字列を比較できます。配列にオブジェクトが含まれている場合は、おそらく JSON.stringify を使用して比較します。

var myArray1 = [1,2,3,4,5],
    myArray2 = [2,1,3,4,5],
    myArray1_sorted = myArray1.slice().sort(),
    myArray2_sorted = myArray2.slice().sort();

//Check to see if the strings are the same or different
console.log( myArray1_sorted.toString() === myArray1.toString() ); //true - sort should not change anything
console.log( myArray2_sorted.toString() === myArray2.toString() ); //false - sort should have changed order
于 2012-05-17T20:16:19.957 に答える
1

Array.sortドキュメントから:

array.sort([compareFunction])

したがって、並べ替え中に少なくとも 1 つの要素の位置が変更されたかどうかを検出する組み込みのソリューション/方法がないことは明らかです。したがって、独自のメソッドを作成する必要があります。

function isAnyElementChangedItsPosition( unsortedArray, sortedArray ){
   for( var i = 0; i < unsortedArray.length; ++i){
       if( unsortedArray[i] !== sortedArray[i] ){
           return true;
       }
   } 
   return false;
}
于 2012-05-17T20:18:04.253 に答える
1

配列の 2 つのコピーをいじりたくない場合は、並べ替えを開始する前に配列を確認してください。

配列をループして、すべてのアイテムがソートされた位置にある場合 (次のアイテムよりも「小さい」と比較する) は true を返し、間違った位置で 1 つのアイテムが検出されるとすぐに false を返すことができます。

オブジェクトを使用しているため、比較コードはオブジェクトの並べ替え方法によって異なります。

于 2012-05-17T20:41:16.557 に答える
0

どういうわけか配列を比較する必要があります。配列を簡単に複製してチェックを行うことができます。

  var arr = [5, 4, 1, 6]
  var arrBefore = arr.slice(0);
  arr.sort()

  for(var i =0; i< arr.length; i++) { 
    if (arrBefore[i] !== arr[i]) {
      // a change was made
    }
  } 
于 2012-05-17T20:16:08.987 に答える
0

要するに、組み込み関数はありません。等しいかどうかを確認する必要があります。

等しいかどうかを確認する 1 つの方法を次に示します。

function arraysEqual(a, b) {

    // Are the lengths the same?
    var i = a.length;
    if (i !== b.length)
        return false;

    // Are all the values the same?
    while (i --) {
        if (a[i] !== b[i])
            return false;
    }

}

これは配列であるかどうかをチェックしないことに注意してください。arraysEqual("abc", ["a", "b", "c"])本当です。必要に応じて、このチェックを追加できます。

于 2012-05-17T20:17:41.603 に答える
0

あなたが望むことをするための組み込み関数はありません。

これはどう:

function isArraySorted(array) {
    if (!array.length) {
        return true;
    }
    var lastElement = array[0];
    for (var i = 1; i < array.length; i++) {
        if (array[i] <= lastElement) {
            return false;
        }
        lastElement = array[i];
    }
    return true;
}

alert(isArraySorted([1,2,3]) + " " + isArraySorted([1,2,3,2.5]));

var array = [1,2,3];

if (!isArraySorted(array)) {
    // No need to do the sort if the array is already sorted.
    array.sort();
}
于 2012-05-17T20:17:50.840 に答える
0

文字列や並列配列が行うため、データを複製しません。

function chkOrder(a) {
  for(var i =1; i< a.length; i++)
    if (a[i-1] > a[i]) return false;
  return true;
}

順序を逆にする場合は、">" 記号で作業する必要がある場合があります。これは、最初の出現時に false (順序付けされていない) も返します。

含まれているオブジェクトを制御できる場合は、オブジェクトの変更を制御し、親の並べ替えを開始できます

function O(parent,data) {//initialize with parent and value array/object
  this.parent=parent;
  this.data=data;
  //shortcurt to sort parent
  this.sort=function()
    {console.log("sortingparent");this.parent.sort(this.parent.sortfunc);}
  this.setData=function(data) {
  this.data=data;
  this.sort();
}
//if changes can be groupped then is more efficient to signal parent dirty and sort latter
this.setKey=function(key,value) {//change value in the data
  if (key==parent.sortkey&&value!=this.data[key]) {
    this.data[key]=value;
    this.sort();
  } else this.data[key]=value;
}
this.parent.push(this);
  this.sort();
  return this;
}
//-------
//using a simple array, this could also be and object and have specific func's
var arr=[];
//example, sort by name, ascending
arr.sortkey="name";
//closure to build a sort predicate bound to the used key
function setkey(key) {return function(a,b) {return a.data[key]>b.data[key];}}
arr.sortfunc=setkey(arr.sortkey);
var b=new O(arr,{name:"B",value:0});
var c=new O(arr,{name:"C",value:2});
var a=new O(arr,{name:"A",value:1});
var d=new O(arr,{name:"D",value:3});
console.log("changing value");
a.setKey("value",100);//when not sorting by value its the same as a.data.value=100
console.log("changing name");
a.setKey("name","X");//this will fire parent sort
for(n=0;n<arr.length;n++) console.log(arr[n].data.name,"=",arr[n].data.value);
于 2012-05-17T20:28:25.670 に答える
-1
var data = [
    { 'value' : 5, 'name' : 'foo'},
    { 'value' : 3, 'name' : 'bar'},
    { 'value' : 10, 'name' : 'js'}
];

var changed = sortAndReport(data, byValue);

// sortAndReport :: [a], (a, a -> Number) -> Boolean
// Sorts an array according to the provided Array.prototype.sort
// compare function and returns a Boolean indicating whether
// sorting changed the order of the array.
function sortAndReport(a, fn) {
    var changed = false;

    a.sort(function (a, b) {
        var sortResult = fn(a, b);
        changed        = sortResult > 0;
        return sortResult;
    });

    return changed;
}

// byValue :: { value :: Number }, { value :: Number } -> Number
function byValue(a, b) {
    return a.value - b.value;
}
于 2012-05-17T20:11:16.550 に答える