【问题标题】:Break a array into n chunks with overlapping start element将数组分成 n 块,起始元素重叠
【发布时间】:2021-10-05 11:05:35
【问题描述】:

我有以下问题,我需要将一个数组拆分为至少 n 个偶数块,但是每个数组的第一个元素除了第一个元素是前一个数组的最后一个元素。如果没有足够的元素,最后一个数组可以包含较少数量的元素。

~@trincot 发现的边缘情况

如果无法拆分为 n 个请求的块, 在可能的情况下拆分为最接近的块数。

输入:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

预期输出 n=3:

[[1, 2, 3, 4, 5], [5, 6, 8, 9, 10], [10, 11]]

我需要 JavaScript 的解决方案,但可以随意提交其他语言,我会翻译并提交 JavaScript 的解决方案。

我的尝试无效,我不知道如何从所需的块号开始,所以我在这里使用了块大小,打算稍后从块号中找出块大小。

let array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
const range = 4;
const res = [array.slice(0, range)];

let start = range;
let end = range * 2;
while (true) {
  console.log(start, end);
  res.push(array.slice(start, end));
  start += range;
  end += range;
  if (start >= array.length) {
    break;
  }
}

console.log(res);

【问题讨论】:

  • 嗨,到目前为止,您尝试了什么?
  • 我尝试编写一个工作解决方案约 2 小时,这是一个简单的问题,但我无法正确解决,真的不知道为什么。我的解决方案在输出的开始/结束时存在元素问题。所以我决定在这里发布它以节省时间和挫败感。
  • 您可以展示您的解决方案并请求社区帮助修复它。
  • 嗨@DamianGrzanka,我们理解你的感受!请分享您的代码。不工作也没关系
  • 这能回答你的问题吗? Split array into chunks

标签: javascript arrays algorithm


【解决方案1】:

这是一个产生结果的映射函数:

const overlapSplit = (arr, length) => {
    let chunk = 1 + Math.max(1, Math.ceil((arr.length - 1) / length));
    if (length > 1 && (chunk - 1) * (length - 1) + 1 > arr.length) return overlapSplit(arr, length - 1);
    return Array.from({length}, (_, i) =>
        arr.slice(i * chunk - i, i * chunk - i + chunk)
    );
}  

console.log(overlapSplit([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], 6));

【讨论】:

  • 谢谢,它正在工作。我不知道以这种方式创建数组是可能的。非常聪明的解决方案:)
  • 但我仍然需要弄清楚如何将输入数组大小和块数转换为块大小
  • 块大小不是输入参数吗?我可能误会了。更新:我明白了。但这提出了一个问题,我在另一条评论中提出。你能回答吗?
  • 我在你提出问题的地方回答了
  • 我更新了我的答案,所以参数是 number 个块,但请注意,这并不总是可能与 equally大小的块,最后一个块除外。所以对于某些值,这会产生奇怪的结果。让我知道你想如何处理这些案件。请参阅我的其他评论与示例案例。
【解决方案2】:

此版本将其拆分为n 块,大小尽可能接近。

也就是说,1 - 11 分为四个块,需要重叠,变为:[1, 2, 3, 4][4, 5, 6, 7][7, 8, 9][9, 10, 11]。请注意,它们都具有三个或四个元素,并且具有四个的元素排在具有三个的元素之前。

const getIndices = (n, g, a = 0, c = Math .ceil (n / g) ) => 
  (n < 1 || g < 1) ? [] : [c + a, ... getIndices (n - c, g - 1, c + a - 1)]

const equalishChunks = (xs, g) =>
  getIndices (xs .length + g - 1, g) 
    .map ((n, i, a) => xs .slice ((a [i - 1] || 1) - 1, n))

console .log (equalishChunks ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], 3))
console .log (equalishChunks ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], 4))
console .log (equalishChunks ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], 6))
.as-console-wrapper {max-height: 100% !important; top: 0}

我们分两部分解决问题。首先,我们找到需要破坏数组的索引(在对getIndices 的调用中),然后我们在这些索引处破坏数组(在.map 调用中。)

getIndices 重复剩余要处理的组数 (g),使用要分组的项目数 n、累加器 a 和当前值 c,其中只是ng 商的上限。这不是一个通用函数,因为您不寻常的重叠要求在这里由递归调用的最终参数中的- 1 处理。例如对于四个块中的1 - 11,这将返回[4, 7, 9, 11]

equalishChunks 将重叠值的数量(比组数少一)添加到数组的长度,调用getIndices 然后映射它们,在这些索引处拆分数组(再次处理重叠由- 1(a [i - 1] || 1) - 1 中的第二个。|| 1 仅用于处理不存在a [i - 1] 的第一个索引。

【讨论】:

    猜你喜欢
    • 2015-03-28
    • 1970-01-01
    • 2011-03-31
    • 2022-11-29
    • 1970-01-01
    • 2020-06-20
    • 2015-10-18
    • 2014-04-11
    • 2015-02-02
    相关资源
    最近更新 更多