написать функцию преобразования строки в массив подстрок определенной длины с помощью reduce

Даны строка, например, str = 'abcdefghijklmnopqrstuvwxyz' и длина подстроки nmb.

Необходимо написать функцию (str, nmb) => {} которая преобразует строку в массив подстрок, длина которых равна nmb. Решил через обычный цикл, но необходимо через reduce

let str = 'abcdefghijklmnopqrstuvwxyz'; //
let strToArr = str.split('');
console.log(strToArr)
let nmb = 6;

function dividedArr(str, nmb) {
  let mc = Math.ceil(str.length / nmb)
  let arr = []
  let start = 0
  for (let i = 0; i < mc; i++) {
    arr[i] = str.slice(start, start + nmb)
    start += nmb
  }
  console.log(arr)
}

dividedArr(str, 3)
dividedArr(str, 5)

Используя reduce смог решить частично: формируется один элемент массива с заданным количеством символов nmb в элементе:

let str = 'abcdefgh'; //ijklmnopqrstuvwxyz'
let nmb = 4
let arr = str.split('')
console.log(arr)
let i = 0
let arr2 = []

let result = arr.reduce((acc, item) => {
  if (i < nmb) {
    acc += item
    i++
  }
  return acc
}, [])
arr2.push(result)

console.log(arr2)


Ответы (3 шт):

Автор решения: Zhihar

так устроит?

arr.reduce((acc, item) => {
    if (i < nmb) {
        acc += item
        i++
    }
    else {
        arr2.push(acc)
        i = 0
        acc = ''
    }
    return acc
}, [])

или вот такой вариант - без лишних внешних переменных

arr2 = arr.reduce((acc, item, index) => {
    if (acc[acc.length - 1].length < nmb) {
        acc[acc.length - 1] += item
    }
    else {
        acc[acc.length] = item
    }
    
    // избавиться от последнего элемента массива, если его размер меньше nmb
    if ((index === arr.length - 1) && (acc[acc.length - 1].length !== nmb)) {
        acc.pop();
    }
    
    return acc
}, [''])
→ Ссылка
Автор решения: entithat

Чтобы не засорять ответ неоптимальным решением, можете посмотреть правки к этому ответу.

В общем, можно изначально посчитать количество частей и в функции reduce находить индекс елемента, в который нужно записывать букву. Индекс ищем с помощью такой операции Math.floor(ind / len), где ind - числа от 0 до str.length - 1, len - длинна части. Соответственно (если подставить числа), индексы будут такие 0 0 0 0 1 1 1 1 и тд., если len = 4.

const str = 'abcdefghijklmnopqrstuvwxyz';
const len = 4;

console.log(Array.from(str).reduce((acc, cur, ind) => {
  acc[Math.floor(ind / len)] += cur;
  return acc;
}, Array.from({ length: Math.ceil(str.length / len) }, () => '' )));
// Тут мы просто сразу синициализировали массив ['', '', '', '', ...]

→ Ссылка
Автор решения: DiD
[...str].reduce((r,c)=>{ 
  if (r[r.length-1].length==4) {
    r.push("");
  } 
  r[r.length-1]+=c; 
  return r;
},[""]);

А можно проще без reduce:

str.split(/(.{4})/g).filter(s=>s)

На тему split еще вариант:

str.replace(/.{4}/g,'$&,').split(',')

Или вот еще через map:

new Array(Math.ceil(str.length/4)).fill().map((v,i)=>str.substr(i*4,4))
→ Ссылка