Javascript 使用对象的多个键和自定义排序逻辑对数组进行排序

Javascript 使用对象的多个键和自定义排序逻辑对数组进行排序,javascript,arrays,sorting,Javascript,Arrays,Sorting,我有一个对象看起来像: var object = [ {"begin":0, "end":20}, {"begin":30, "end":300}, {"begin":40, "end":60}, {"begin":40, "end":50}, {"begin":80, "end":100}, {"begin":80, "end":100}, {"begin":350,"end":370} ] 我希望迭代此对象并按以下形式对其排序:

我有一个对象看起来像:

var object = [
    {"begin":0,  "end":20}, 
    {"begin":30, "end":300},
    {"begin":40, "end":60}, 
    {"begin":40, "end":50},
    {"begin":80, "end":100},
    {"begin":80, "end":100},
    {"begin":350,"end":370}
]
我希望迭代此对象并按以下形式对其排序:

0   to 20   -> start here
30  to 300  -> next smallest number from 20 is 30
350 to 370  -> start from previous `end`, next number after 300 is 350.

// now, since there is no larger number than 370, start loop again.
40  to 60   -> start from 40 since this is the smallest unused number
80  to 100  -> next unused smallest number from 60 is 80

// now, since there is no larger unused number than 100, start loop again.
40  to 50
80  to 100
返回相同数组或新数组都可以


感谢您的帮助。

Javascript数组有一个
排序
方法,可以将比较函数作为参数:

var data = [...]; // your data here
data.sort(function(a, b) {
    // insert your logic here
    // return values:
    //  -1 (a less than b)
    //   0 (a equal to b)
    //   1 (a greater than b)
});

还有更多这种方法的例子。

对于您想要做的事情,常规排序(即使使用自定义函数)可能不会对整个事情起作用

但是,您应该使用它以良好的顺序获取元素,以便进一步处理。先按开始排序,然后按结束排序

然后,如果您向每个数据集添加一个“dirty”标志,它将变得更加容易

var obj = [
    {"begin":0,  "end":20,   "dirty": false}, 
    {"begin":30, "end":300,  "dirty": false},
    {"begin":40, "end":60,   "dirty": false}, 
    {"begin":40, "end":50,   "dirty": false},
    {"begin":80, "end":100,  "dirty": false},
    {"begin":80, "end":100,  "dirty": false},
    {"begin":350,"end":370,  "dirty": false}
];

function getNextSet(arr)
{
  var ret = [];
  var lastEnd = -1;

  for (var i = 0; i < arr.length; i++)
  {
     if (arr[i].begin >= lastEnd && arr[i].dirty == false)
     {
        ret.push(arr[i]);
        arr[i].dirty = true;
        lastEnd = arr[i].end;
     }
  }

  return ret;
}

// do custom sorting as mentioned in the other answer to get in a good starting state

var set = [];
do {
  set = getNextSet(obj);
  // do whatever
} while (set.length != 0);
var obj=[
{“开始”:0,“结束”:20,“脏”:假},
{“开始”:30,“结束”:300,“脏”:假},
{“开始”:40,“结束”:60,“脏”:假},
{“开始”:40,“结束”:50,“脏”:假},
{“开始”:80,“结束”:100,“脏”:假},
{“开始”:80,“结束”:100,“脏”:假},
{“开始”:350,“结束”:370,“脏”:假}
];
函数getNextSet(arr)
{
var-ret=[];
var lastEnd=-1;
对于(变量i=0;i=lastEnd&&arr[i].dirty==false)
{
再推(arr[i]);
arr[i].dirty=true;
lastEnd=arr[i]。结束;
}
}
返回ret;
}
//按照另一个答案中提到的进行自定义排序,以获得良好的启动状态
var集=[];
做{
set=getNextSet(obj);
//做任何事
}while(set.length!=0);

请参见此处的工作示例:


在第一个排序的子集中,您为什么选择30到300呢?很难分辨您是什么asking@Anurag:因为从20开始的下一个最小数字是30。请更详细地解释所需的排序顺序。为什么
40到60
要在350到370之后呢?@jfriend00:我更新了问题的更多细节:)我认为标准的
sort()
函数不符合OP的用例,它需要多次传递数据。这不是一个解决方案/答案。这是一个可以使用的工具(可能属于注释),但甚至不接近完整的答案。这个问题的主要部分是如何实现这种类型的自定义排序算法。
ret.append()
应该是
ret.push()
。但是即使有了这个修正,我在最后还是得到了
set=[]
-可能
做任何事情
行需要更多说明:)这就是你使用集合中数据的地方。while循环之后,集合将始终为[]-这就是循环如何知道列表中没有更多要处理的项。
function sortItems(items) {
    items = items.slice() // make a copy
        // sort by "begin", in case the 
        // data isn't pre-sorted
        .sort(function(a,b) {
            return a.begin - b.begin;
        });
    var sorted = [], 
        idx = 0, 
        item;
    while (items.length) {
        // move the current item into the sorted array
        item = items.splice(idx, 1)[0];
        sorted.push(item);
        // find next index
        for (; idx<items.length; idx++) {
            if (items[idx] && items[idx].begin > item.end) {
                break;   
            }
        }
        // reset to 0 if we went too far
        idx = idx < items.length ? idx : 0;
    }
    return sorted;
}
var arr = [
    {"begin":0,  "end":20}, 
    {"begin":30, "end":300},
    {"begin":40, "end":60}, 
    {"begin":40, "end":50},
    {"begin":80, "end":100},
    {"begin":80, "end":100},
    {"begin":350,"end":370}
];
sortItems(arr); // sorted as you specify