JS排序 - 确定是否有任何变化?

时间:2012-05-17 20:04:55

标签: javascript sorting

我正在使用array.sort对对象数组进行排序。

有没有办法确定这些对象的顺序是否发生变化而不是自己进行比较?一些内置JS功能?我不需要知道变化的数量,只需要至少有1个变化。

更新

我正在对自定义对象进行排序,例如:

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

更新2:

我正在考虑在生成对象时添加一个额外的自定义属性“order”,然后在.sort之后检查'order'是否顺序。有更快/更好的方法吗?

8 个答案:

答案 0 :(得分:3)

没有任何内置可以满足您的要求。如果它是一个简单的数组,你可以使用join / toString()并比较两个最终的字符串。如果数组包含对象,可能会使用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

答案 1 :(得分:1)

如果您不想弄乱阵列的两个副本,请在开始排序之前检查阵列。

如果每个项目都在其排序位置,您可以遍历数组并返回true, (比较下一项比较'少')或者只要在错误的位置检测到一个项目就会假。

由于您正在使用对象,因此比较代码取决于您对对象进行排序的方式。

答案 2 :(得分: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
    }
  } 

答案 3 :(得分:0)

简而言之:没有内置功能,你必须检查是否平等。

这是检查平等的一种方法:

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"])是真的。如果需要,可以添加此检查。

答案 4 :(得分: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();
}

答案 5 :(得分:0)

来自Array.sort docs:

array.sort([compareFunction])

所以很明显,没有内置的解决方案/方法来检测在排序过程中是否至少有一个元素改变了它的位置。所以你需要编写自己的方法:

function isAnyElementChangedItsPosition( unsortedArray, sortedArray ){
   for( var i = 0; i < unsortedArray.length; ++i){
       if( unsortedArray[i] !== sortedArray[i] ){
           return true;
       }
   } 
   return false;
}

答案 6 :(得分:0)

不重复数据,因为字符串和并行数组都可以。

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

您可能需要处理“&gt;”如果您撤销订单,请签名 这也会在第一次出现时返回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);

答案 7 :(得分:-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;
}