按其值对数组对象进行分组 - javascript

时间:2018-05-16 21:32:34

标签: javascript arrays javascript-objects

我正在尝试根据对数组值的某些操作来计算将数组分组为多个数组的最佳方法

例如,我的数组看起来像

var arr = [100, 200, 300, 500, 600, 700, 1000, 1100, 1200]

只要差值超过100,我就需要将上面的数组分组到不同的数组中。

所以我的输出看起来像是:

var result = [[100, 200, 300], [500, 600, 700], [1000, 1100, 1200]]

实现这一目标的最佳方法是什么?

我尝试了传统的for循环,如果条件检查下一个元素与当前元素之间的差异,继续将其推送到数组,当差异大于100时创建一个新数组。

我认为需要有更好的方法来实现它。

编辑: -

我已经尝试了以下代码,它的关闭但不完整。没有花更多的时间在上面,因为我试图使用reduce或下划线来获得更简单的版本 -

var result = [], temp = [], difference;
for (var i = 0; i < array.length; i += 1) {
 if (difference !== (array[i + 1] - array[i])) {
    if (difference !== undefined) {
        result.push(temp);
        temp = [];
    }
    difference = array[i + 1] - array[i];
}
temp.push(array[i]);
}

if (temp.length) {
  result.push(temp);
}

3 个答案:

答案 0 :(得分:0)

您可以使用reduce来完成此操作。

var arr = [100, 200, 300, 500, 600, 700, 1000, 1100, 1200];

var groups = arr.reduce(function (a, b) {
  if (a.length === 0) { // First Iteration
    a.push([b]);
    return a;
  }

  var lastGroupIndex = a.length - 1;
  var lastGroup = a[lastGroupIndex];

  var lastElementIndex = lastGroup.length - 1;
  var lastElement = lastGroup[lastElementIndex];

  if (b - lastElement <= 100) { // Add to current group
    lastGroup.push(b);
    return a;
  }

  a.push([b]); // Create new group
  return a;
}, [])

注意:此解决方案不使用ES6功能。我在最初的问题中使用var假设代码库不在ES6上,并在评论中发现这个假设是正确的。

答案 1 :(得分:0)

这是一个有趣的问题。

编辑:重新阅读后,不清楚输入数组是否已排序。如果它已排序,您可以查看reduce调用。

起初,我想知道是否有比O(nlogn)更优的解决方案。但是,即使您是分段项目,最终的超级阵列仍然是完全排序的。因此,如果O(nlogn)存在更快的方法来解决您的问题,您还可以比nlogn更快地解决排序。

鉴于此,最直接的解决方案是对数组进行排序,然后在迭代时将其相应地分配给最后一个元素。 Reduce最终成为一个完美的工具:

&#13;
&#13;
const input = [100, 200, 300, 500, 600, 700, 1000, 1100, 1200];

const sorted = input.slice().sort((a, b) => a - b);

const buckets = sorted.reduce((buckets, item, i) => {
  const lastBucket = buckets[buckets.length - 1];
  if (i === 0) {
    return [[item]];
  }
  const prev = sorted[i - 1];
  if (item - prev > 100) {
    buckets.push([item]);
  } else {
    buckets[buckets.length - 1].push(item);
  }
  return buckets;
}, [])
console.log(buckets);
&#13;
&#13;
&#13;

答案 2 :(得分:0)

由于在一个函数中没有使用reduce的完整基础的答案:

var arrOrg = [100, 200, 300, 500, 600, 700, 1000, 1100, 1200]
arrOrg.reduce(function (acc, item, idx, arr) {
  if (idx) {
    (idx < arr.length && arr[idx + 1] > item + 100) // the spec condition
      ? acc[acc.length] = [item]
      : acc[acc.length - 1].push(item)
  } else acc[0][0] = item
  return acc
}, [[]])

注意它会返回

[[]]

用空数组调用时,不应该吗?

另请注意,它不关心排序。