Я пытаюсь разбить массив, который имеет повторяющийся шаблон элементов 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]);
}
}
Любая помощь очень ценится, спасибо!
Это не 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 хранит ссылки на объекты.
Отлично, я следил за вашим редактированием, и это сработало! Большое спасибо! Аллилуйя!
Я бы добавил помощника 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))
Спасибо, это имеет смысл для меня. Однако я новичок в этом и не знаю, куда именно вставлять имена моих новых массивов? Четыре имени upload_names, upload_ids, upload_info_circle_class и upload_info_circle_content.