将数组分成子集

时间:2016-04-10 04:02:40

标签: javascript arrays sorting subset

我试图让这个函数将数组拆分成子集。每个子集的数字应与前一个数字相同,或者与前一个数字相差1。 我下面的例子应该返回两个子集,但它返回{0,1,2,3}。对我做错了什么的想法?此外,是否有更好的方法为每个新子集动态创建一个数组?感谢

function max_tickets() {
    var arr = [4, 13, 2, 3];
    var myarr = arr.sort(function(a, b){return a-b});


for(var i = 0; i<myarr.length; i++){

    var iplus = i+1;
    if(i === i || i === iplus){
       newArr= [];
       newArr.push(i);
    }else if (i !== i || i !== iplus){
       arr2 =[];
       arr2.push(i);
  }
 }
}

3 个答案:

答案 0 :(得分:2)

您尝试做的通常称为“分区”。该问题的通用版本是使用一些“规则”或谓词或条件将数组分区为子数组,该规则指定特定元素应该进入哪个分区,或者指定它应该进入新分区

执行此操作的伪代码为:

To partition an array:
  Initialize the resulting array
  For each element in the array
    If that element starts a new chunk
      Create a new empty chunk in the resulting array
   Add the element to the most recent chunk
   Return the result

这可以在JS中直接表达为

function partition(array, fn) {
  return array.reduce((result, elt, i, a) => {
    if (!i || !fn(elt, i, a)) result.push([]);
    result[result.length - 1].push(elt);
    return result;
  }, []);
}

现在我们需要写一个函数说明何时应该启动一个新分区:

// Is the element within one of the previous element?
function close(e, i, a) {
  return Math.abs(e - a[i-1]) > 1;
}

我们现在可以用

对数组进行分区
partition([[4, 13, 2, 3], close)

答案 1 :(得分:1)

这应该有用。

function max_tickets() {
    var arr = [4, 13, 2, 3];
    var myarr = arr.sort(function (a, b) { return a - b });
    arrSubsets = [];
    arr1 = [];
    for (var i = 0; i < myarr.length; i++) {
        if (myarr[i - 1] === undefined) {
            arr1.push(myarr[i]);
            continue;
        }
        if (myarr[i] - myarr[i - 1] <= 1) {
            arr1.push(myarr[i]);
        }
        else {
            arrSubsets.push(arr1);
            arr1 = [];
            arr1.push(myarr[i]);
        }
    }
    if (arr1.length > 0)
        arrSubsets.push(arr1);                    
}
max_tickets();

答案 2 :(得分:1)

根据您的问题:

  • 对我做错了什么的想法?。

在循环内部,您使用的是i,就好像它是数组的值一样,但是在您的特定情况下,循环从0变为myarr.length的值{{ 1}},以便4的值为i

正如您所看到的,您正在使用0, 1, 2, 3的值进行比较,而不是使用数组的值来使用数组的值,您必须指定index,您的案例arrayname[index]会为您提供值myarr[i]

  • 另外,有没有更好的方法为每个新子集动态创建一个数组?

是的,您可以在循环内动态地在另一个数组内创建一个数组:

4, 13, 2, 3

正如您在上一个示例中所看到的,我在var b = []; for(var i = 0; i < 10; i++){ b.push(['I am' + i, i]); } 数组内部创建了一个数组,因此一旦循环结束,b数组内部将有10 b个每个2个元素。