javascript - JS Sort - Determine if Anything Changed? - Stack Overflow

I'm using array.sort to sort an array of objects.Is there someway to determine if the order of tho

I'm using array.sort to sort an array of objects.

Is there someway to determine if the order of those objects changed other than doing a parison myself? Some in-built JS function? I don't need to know the # of changes, just that there was at least 1 change.

Update:

I'm sorting custom objects, e.g.:

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

Update 2:

I'm considering adding an additional custom property 'order' as I generate the objects and then checking to see if 'order' is or isn't sequential after the .sort. Is there a faster/better method?

I'm using array.sort to sort an array of objects.

Is there someway to determine if the order of those objects changed other than doing a parison myself? Some in-built JS function? I don't need to know the # of changes, just that there was at least 1 change.

Update:

I'm sorting custom objects, e.g.:

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

Update 2:

I'm considering adding an additional custom property 'order' as I generate the objects and then checking to see if 'order' is or isn't sequential after the .sort. Is there a faster/better method?

Share Improve this question edited May 17, 2012 at 20:52 Chad asked May 17, 2012 at 20:04 ChadChad 3,2374 gold badges37 silver badges45 bronze badges 6
  • So you want to know if they weren't in order when you called sort? – Jivings Commented May 17, 2012 at 20:08
  • 3 what kind of objects are you sorting? having control over them will be nice and efficient if the changing objects could signal the array as dirty or fire the sort themselves – neu-rah Commented May 17, 2012 at 20:18
  • 1 Yes, if you care about performance, track when and how the array is actually changed. – We Are All Monica Commented May 17, 2012 at 20:20
  • But changing the array does not necessarily change the sort order. – HBP Commented May 17, 2012 at 20:22
  • @neu-rah - see my updates. Yes, I have control over them. Could you elaborate on your idea? – Chad Commented May 17, 2012 at 20:52
 |  Show 1 more ment

8 Answers 8

Reset to default 3

There is nothing built in that does what you are asking. If it is a simple array you can just use join/toString() and pare the two final strings. If the array contains objects, probably would use JSON.stringify and pare.

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

If you don't want to mess with two copies of the array, check the array before starting the sort.

You can loop through the array and return true if every item is in its sorted position, (pares 'less' than the next item) or false as soon as one item is detected in the wrong position.

Since you are using objects, the parison code depends on the way you are sorting the objects.

From Array.sort docs:

array.sort([pareFunction])

So it is obvious, there is no built-in solution/method for detecting whether at least one element has changed its position during the sorting. So you need to write your own method:

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

You have to pare the arrays somehow. You can easily clone an array and make the check:

  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
    }
  } 

In short: no built-in function, you've gotta check for equality.

Here's one way to check for equality:

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;
    }

}

Note that this doesn't check if they're arrays; arraysEqual("abc", ["a", "b", "c"]) is true. You can add this check if you want.

There's not a built-in function to do what you want.

How about this:

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();
}

Not duplicating data, becase strings and parallel arrays do.

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

you might need to work on th ">" sign if you reverse the order this will also return false (not ordered) on first occourence

if we can control the contained objects then we can control changes in the objects and fire a parent sort

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);
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
// pare 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;
}

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745349741a4623758.html

相关推荐

  • javascript - JS Sort - Determine if Anything Changed? - Stack Overflow

    I'm using array.sort to sort an array of objects.Is there someway to determine if the order of tho

    3小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信