【问题标题】:breaking an array into subsets将数组分解为子集
【发布时间】:2016-04-10 04:02:39
【问题描述】:

我正在尝试使用此函数将数组拆分为子集。每个子集的数字都等于前一个数字或与前一个数字相差 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);
  }
 }
}

【问题讨论】:

  • [4, 13, 2, 3] 示例的期望输出是什么?

标签: javascript arrays sorting subset


【解决方案1】:

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

执行此操作的伪代码是:

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)

【讨论】:

    【解决方案2】:

    这应该可行。

    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();
    

    【讨论】:

    • 谢谢,我添加了几行代码,效果很好。
    【解决方案3】:

    根据您的问题:

    • 知道我做错了什么吗?

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

    如您所见,您使用index 的值进行比较,而不是使用数组的值来使用数组的值,您必须指定arrayname[index],在您的情况下为@987654329 @ 这将为您提供值:4, 13, 2, 3

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

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

    var b = [];
    for(var i = 0; i < 10; i++){
      b.push(['I am' + i, i]);
    }
    

    正如您在前面的示例中看到的,我在 b 数组内创建了一个数组,因此一旦循环完成,b 数组将在其中包含 10 个 arrays,每个数组有 2 个元素。

    【讨论】:

    • 这可能会让事情变得有点不对劲……非常感谢您指出这一点。很酷的个人资料图片顺便说一句
    猜你喜欢
    • 2020-09-26
    • 2016-05-02
    • 1970-01-01
    • 1970-01-01
    • 2018-05-24
    • 2017-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多