Three-way compare function for Arrays in Javascript

杀马特。学长 韩版系。学妹 提交于 2019-11-29 17:12:37

I'd go with a generic comparison-maker function to be used in a functional way:

function compareArrays(compareItems) {
    return function(a, b) {
        for (var r, i=0, l=Math.min(a.length, b.length); i<l; i++)
            if (0 != (r = compareItems(a[i], b[i])))
                return r;
        return a.length - b.length;
     };
}
// Examples:
var compareNumberArrays = compareArray(function(a,b){ return a-b; }),
    compareGenericArrays = compareArray(function(a,b){ return +(a>b)||-(b>a); });

Now you can use

[ [4,5,10], [4,5,6], [4,1,2], [4,5] ].sort(compareNumberArrays)

Is there something more like a one-liner, or must I define my own function whenever I want to do this?

Comparing arrays is too complex for a one-liner, you should use a helper function. There's no built-in one that you can use everywhere.

Probably not the shortest possible, but the fewest lines I can get to sensibly is:

function compareArrays(lhs, rhs) {
  var result;
  lhs.some(function(v, i) {
    return (result = v - rhs[i]);
  });
  return result;
}

or less sensibly:

function compareArrays(lhs, rhs, r) {
  lhs.some(function(v, i) {return (r = v - rhs[i])});
  return r;
}

Edit

Seems you don't want numbers. The compare part can be any relationship you want, e.g. for strings:

function compareArrays(lhs, rhs, r) {
  lhs.some(function(v, i) {return (r = v < rhs[i]? -1 : v > rhs[i]? 1 : 0)});
  return r;
}

[['a','b','c'],['a','c','d'],['a','b','d']].sort(compareArrays) // a,b,c,a,b,d,a,c,d 

But the compare function needs to know what it's getting so it doesn't sort numbers as strings or strings as numbers (and so on…).

If you know that they are always triplets of numbers (arrays of length 3), you could do this:

function combineNum(array) {
    return (array[0] * 100) + (array[1] * 10) + array[2];
}

function compareArrays(lhs, rhs) {
    return combineNum(rhs) - combineNum(lhs);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!