【问题标题】:Javascript : looping array of arrays. If match found, push to array, if not, create new innerarrayJavascript:循环数组。如果找到匹配,则推送到数组,如果没有,则创建新的内部数组
【发布时间】:2015-06-29 15:42:13
【问题描述】:

我正在从数据库中检索信息。数据看起来像这样(我已经简化了):

    var example = [
    {'start': 1966, 'end': 1970},
    {'start': 1969, 'end': 1971},
    {'start': 1972, 'end': 1980},
    {'start': 1974, 'end': 1985},
    {'start': 1975, 'end': 1979},
    {'start': 1986, 'end': 1990},
    {'start': 1991, 'end': 1995}
          ];

我想要做的是动态地将它排序到一个新的空数组newArr。排序完成后newArr 应该是这样的

var newArr = [
    [
        {'start': 1966, 'end': 1970},
        {'start': 1972, 'end': 1980},
        {'start': 1986, 'end': 1990},
        {'start': 1991, 'end': 1995}
    ],
    [
        {'start': 1969, 'end': 1971},
        {'start': 1974, 'end': 1985}
    ],      
    [
        {'start': 1975, 'end': 1979}
    ]];

我是 javascript 新手。我选择这种数组和对象组合的原因是因为我使用的是 JSON 数据,其中对象的顺序很重要

我想做什么以及我尝试了什么

我正在尝试将对象分组到主数组的不同键上(newArr[0]、newArr[1] 等。我想遍历 example 并将对象放在某个键上。如果在示例的迭代属性end 低于当时在newArr 上的值,存在重叠,应该创建一个新数组。否则它应该被推入没有重叠的主数组键。我'已经尝试使用以下三个函数来做到这一点

    var newArr = [];

    function _overlap(){
    // place first object
    var addFirst = [example[0]];
    newArr.push(addFirst);

    // place others, therefore start with i = 1;
    for (var i = 1 ; i < example.length ; i++){
        _checkOverlap(example[i]);  
    }   
}   
_overlap();

    function _checkOverlap(input){
    // traverse the main array newArr, example[i] is passed as argument input
    loopJ:{
        for (var j = 0; j < newArr.length; j++){
            // compare value of input.start (so example[i]) with last key of inner array
            var innerArrayLength = newArr[j].length; // I need this to get the last key: length -1
            if (input.start > newArr[j][innerArrayLength-1].end ){
                newArr[j].push(input);
                console.log(newArr);
                break loopJ;                    
            } else {
                _createNewArr(input);
                break loopJ;
            }
        }           
    }
}

    function _createNewArr(input){
    var toBeAdded = [];
    toBeAdded.push(input);
    newArr.push(toBeAdded);
}

这段代码完全符合我对第一个键 newArr0 的要求,但从不推入其他键。在这种情况下我应该使用递归吗?我已经尝试了很多东西,但是由于无限循环而导致浏览器崩溃的数量让我发疯了。

【问题讨论】:

  • 能否假设每个条目中的end大于对应的start,并且example中的条目按start排序?
  • 看你的预期输出我不明白你是如何排序的
  • @Oriol :是的,它总是更大。并且起始值是 sorted ,它来自一个排序的 mysql 查询,最低值在前,然后降序。
  • 那么,如果start小于或等于之前添加的区间的end,你想要一个新数组吗?
  • @depperm :我可能在某个地方感到困惑。基本上我想要做的是:将 input.start 的值与内部数组键的最高值进行比较。因此,如果我有 newArr[0]、newArr[1] 和 newArr[2],例如 newArr[0] 有 6 个条目(所以最高键是 5),newArr[1] 有 12 和 newArr[2 ] 有 5,我想比较(如果 input.start 高于它,则立即停止) input.start 与 newArr[0][5], newArr[1][11], newArr[2][[4]并在满足条件时推送它并打破循环。如果条件从未满足,我想创建一个新数组。

标签: javascript arrays json loops object


【解决方案1】:

如果我理解正确,对于example 的每个条目,您必须搜索newArr 中可以添加条目的第一组。如果找到该组,请添加条目并迭代下一个条目。如果您没有找到该组,只需在最后创建一个新组即可。

var newArr = [];
outerloop:
for(var entry of example) {
  for(var group of newArr)
    if(group[group.length-1].end < entry.start) {
      group.push(entry);
      continue outerloop;
    }
  newArr.push([entry]);
}

【讨论】:

  • 这比我想的递归方法更容易阅读,太棒了!
  • 我一直把头撞在墙上,试图写这么多行代码只是为了退格,现在我看到了。如此优雅,简短且有效。非常感谢!我会花时间看看你做了什么并理解它:)
【解决方案2】:

为什么不在arr.sort 中使用比较器函数

 var example = [
{'start': 1966, 'end': 1970},
{'start': 1969, 'end': 1971},
{'start': 1972, 'end': 1980},
{'start': 1974, 'end': 1985},
{'start': 1975, 'end': 1979},
{'start': 1986, 'end': 1990},
{'start': 1991, 'end': 1995}
      ];

//sorting using comparator function
example.sort(function(a,b){return a.start-b.start}) //will sort on start date

【讨论】:

  • 他不想对其进行排序,他想排除重叠的年份间隔并将它们放在不同的组中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-15
  • 1970-01-01
  • 1970-01-01
  • 2016-05-18
  • 2018-05-30
  • 1970-01-01
  • 2021-12-31
相关资源
最近更新 更多