Javascript: разбить массив по шаблону: элементы 1, 5, 10, затем 2, 6, 11, затем 3, 7, 12

Я пытаюсь разбить массив, который имеет повторяющийся шаблон элементов 1, 2, 3 и 4. Я хочу превратить свой массив [1,2,3,4,5,6,7,8,9,10] на четыре массива: [1,5,10], [2,6,11], [3,7,12] и [4,8,13]. Я пытался использовать кратные, но результат создает новые массивы в неправильном порядке. Вот моя попытка:

var upload_names_and_ids = [

    "Certificat de salaire", //first line is the upload's visible title
    "certificat-de-salaire", //second line is the upload's id
    "no-info-circle", //third line is the info-circle class
    "", //fourth line is the info-circle text
    
    "Allocations Familiales",
    "alloc-familiales",
    "no-info-circle",
    "",
    
    "Courrier Impot (déclaration précédente)",
    "courrier-impot",
    "info-circle right",
    ""
    
];

//Seperate our first array into 4

var upload_names = [];
var upload_ids = [];
var upload_info_circle_class = [];
var upload_info_circle_content = [];

for (var i=0; i<upload_names_and_ids.length; i++){
    if (i%4==0) {
        upload_info_circle_content.push(upload_names_and_ids[i]);
    } else if (i%3==0) {
        upload_info_circle_class.push(upload_names_and_ids[i]);
    } else if (i%2==0) {
        upload_names.push(upload_names_and_ids[i]);
    }   else {
      upload_ids.push(upload_names_and_ids[i]);
    }
}

Любая помощь очень ценится, спасибо!

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
58
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Это не i%3==0 (соответствует 0, 3, 6, …), а i%4==1 (соответствует 1, 5, 10, …). То же самое для i%2==0.

Ответ принят как подходящий

Вы можете взять остаток с индексом и желаемой длиной.

const
    array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
    length = 4,
    result = array.reduce(
        (r, v, i) => (r[i % length].push(v), r),
        Array.from({ length }, _ => [])
    );

console.info(result);

Если вы хотите напрямую использовать предварительно объявленный массив, вы можете заменить эту строку

Array.from({ length }, _ => [])

с

[upload_names, upload_ids, upload_info_circle_class, upload_info_circle_content]

где аккумулятор Array#reduce хранит ссылки на объекты.

Спасибо, это имеет смысл для меня. Однако я новичок в этом и не знаю, куда именно вставлять имена моих новых массивов? Четыре имени upload_names, upload_ids, upload_info_circle_class и upload_info_circle_content.

Ben Viatte 15.12.2020 15:02

Отлично, я следил за вашим редактированием, и это сработало! Большое спасибо! Аллилуйя!

Ben Viatte 15.12.2020 15:23

Я бы добавил помощника sliceN, который принимает массив и положительное целое число. Затем возвращает массив массивов, где внутренние массивы имеют длину n.

sliceN([1,2,3,4,5,6,7,8,9], 3) //=> [[1,2,3], [4,5,6], [7,8,9]]
sliceN([1,2,3,4,5,6], 2) //=> [[1,2], [3,4], [5,6]]

Затем также добавьте помощника transpose, который транспонирует матрицу.

transpose([[1,2,3], [4,5,6], [7,8,9]]) //=> [[1,4,7], [2,5,8], [3,6,9]]
transpose([[1,2], [3,4], [5,6]]) //=> [[1,3,5], [2,4,6]]

С помощью этих двух помощников вы с легкостью сможете добиться желаемого результата.

const upload_names_and_ids = [
    "Certificat de salaire", //first line is the upload's visible title
    "certificat-de-salaire", //second line is the upload's id
    "no-info-circle", //third line is the info-circle class
    "", //fourth line is the info-circle text
    
    "Allocations Familiales",
    "alloc-familiales",
    "no-info-circle",
    "",
    
    "Courrier Impot (déclaration précédente)",
    "courrier-impot",
    "info-circle right",
    ""
];

const [
  upload_names,
  upload_ids,
  upload_info_circle_class,
  upload_info_circle_content,
] = transpose(sliceN(upload_names_and_ids, 4));

console.info(upload_names);
console.info(upload_ids);
console.info(upload_info_circle_class);
console.info(upload_info_circle_content);


function sliceN(array, n) {
  const slices = [];
  for (let i = 0; i < array.length; i += n) {
    slices.push(array.slice(i, i + n));
  }
  return slices;
}

function transpose(rows) {
  if (rows.length == 0) return [];
  const columns = rows[0].map(cell => Array.of(cell));
  for (let iRow = 1; iRow < rows.length; iRow += 1) {
    for (let iCol = 0; iCol < columns.length; iCol += 1) {
      columns[iCol].push(rows[iRow][iCol]);
    }
  }
  return columns;
}

Если вы уже используете библиотеку со вспомогательными функциями, скорее всего, присутствует один или оба этих метода преобразования данных. sliceN часто можно встретить как что-то с split, slice или chunk в названии. transpose очень специфичен и, если присутствует, вероятно, будет присутствовать под тем же именем.

В качестве примера Ramda предлагает оба этих метода.

R.transpose(R.splitEvery(4, upload_names_and_ids))

Другие вопросы по теме