根据对象内数字的接近程度减少数组

时间:2017-11-06 17:32:52

标签: javascript arrays reduce

我有一个如下所示的数组:

[  
  { "begin": 870, "end": 889, "spanType": ["plan", "gt-plan"] },
  { "begin": 890, "end": 925, "spanType": ["plan", "gt-plan"] },
  { "begin": 926, "end": 938, "spanType": ["plan", "gt-plan"] },
  { "begin": 939, "end": 958, "spanType": ["plan", "gt-plan"] },
  { "begin": 7732, "end": 7790, "spanType": ["plan", "gt-plan"] },
  { "begin": 7791, "end": 7879, "spanType": ["plan", "gt-plan"] }
]

我需要遍历这个并创建一个如下所示的数组:

[  
  { "begin": 870, "end": 958, "spanType": ["plan", "gt-plan"] },
  { "begin": 7732, "end": 7879, "spanType": ["plan", "gt-plan"] }
]

基本上,如果span.end在下一个span.begin的3之内,则将两个跨度合并在一起

以下是我现在的情况(不工作)see fiddle

spans.forEach(function(d,i) {
    if (i+1 <= spans.length - 1) {
    if (spans[i+1].begin <= d.end + 3) {
    d.end = spans[i+1].end;
     newSpans.push(d);
  }
    else {
        newSpans.push(spans[i]);
    }
  }
});

see fiddle

3 个答案:

答案 0 :(得分:2)

首先,我会对跨度进行排序,这样我们就不需要一遍又一遍地检查所有元素:

spans.sort((a,b) => a.begin - b.begin);

现在我们可以轻松地完成并合并:

const result = [];
result.push(spans.reduce((prev,curr) => {
 if(prev.end < curr.begin - 1){
  result.push(prev);
  return Object.assign({},curr);
 }
 prev.end = Math.max(prev.end, curr.end);
 return prev;
}));

Try it

答案 1 :(得分:1)

对于已排序的数据,您可以使用实际元素检查最后插入的元素,如果增量小于所需数字,则调整end值。

此提案会改变原始数组。如果不需要,则需要在推送时获得对象的副本。

var array = [{ begin: 870, end: 889, spanType: ["plan", "gt-plan"] }, { begin: 890, end: 925, spanType: ["plan", "gt-plan"] }, { begin: 926, end: 938, spanType: ["plan", "gt-plan"] }, { begin: 939, end: 958, spanType: ["plan", "gt-plan"] }, { begin: 7732, end: 7790, spanType: ["plan", "gt-plan"] }, { begin: 7791, end: 7879, spanType: ["plan", "gt-plan"] }],
    result = array.reduce(function (r, o, i) {
        if (!i || o.begin - r[r.length - 1].end >= 3) {
            r.push(o);
        } else {
            r[r.length - 1].end = o.end;
        }
        return r;
    }, []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:0)

&#13;
&#13;
const data = [  
  { "begin": 870, "end": 889, "spanType": ["plan", "gt-plan"] },
  { "begin": 890, "end": 925, "spanType": ["plan", "gt-plan"] },
  { "begin": 926, "end": 938, "spanType": ["plan", "gt-plan"] },
  { "begin": 939, "end": 958, "spanType": ["plan", "gt-plan"] },
  { "begin": 7732, "end": 7790, "spanType": ["plan", "gt-plan"] },
  { "begin": 7791, "end": 7879, "spanType": ["plan", "gt-plan"] }
];

// your range, representing how close an end has to be to a begin to merge
const RANGE = 3;

// iterate through the data still available
for (let i = 0; i < data.length - 1; i++) {
    // check if we should merge the current data object with the next one
    // based on the defined range
    if (data[i].end >= data[i+1].begin - RANGE) {
        // we'll merge the current object into the next one. 
        // first, we'll set the begin value of the next object to
        // the one that's being merged into it
        data[i+1].begin = data[i].begin;

        // now we push the current object's spanType entries into the next object
        Array.prototype.push.apply(data[i+1].spanType, data[i]);

        // finally we remove the current object from the list as it has been
        // fully merged
        data.splice(i, 1);

        // we removed an element, so we'll go one back in the list
        i--;
    }
}
console.log(data);
&#13;
&#13;
&#13;