@boga-net

Как из массива сделать новый массив-матрицу, создав столбцы и колонки?

Здравствуйте. Есть функция, возвращающая нечётное кол-во элементов, например : 3, 8, 15, 24...

Есть функция, которая берёт это значение (кол-во элементов: 3, 8, и т.д.) и создаёт соответствующее кол-во элементов, перемешивает и кладёт в массив. В общем, если проще: жмякаю по кнопке 3 - создаётся массив с тремя элементами в рандомном порядке. Жмякаю по 8, создаётся массив, например: 4, 8, 1, 5, 2, 3, 6, 7.

И, собственно, вопрос, как этот массив [4, 8, 1, 5, 2, 3, 6, 7] разбить так, чтобы получилось 3 строки, и 3 столбца - в соответствии с кол-вом элементов - в данном случае 8. И чтобы матрица имела следующий вид :

let matix = [
  [4, 8, 1],
  [5, 2, 3],
  [6, 7, 0]
]


Ну а если 3 элемента, то :

let matix = [
  [2, 1],
  [3, 0]
]


И чтобы последний элемент тоже попадал в этот массив matrix, в виде нуля. Такое вообще возможно ? Каким методом перебирать ? Вроде Object.entries(matrix) похож на то, что нужно, но, почесав репу, так и не понял, как же это сделать. Может кто сталкивался или имеет представление о том, как решить эту задачу. Может нужно копать в сторону .join и .split ? Ума не приложу. Я не прошу решать задачу, но хотя бы подсказать, куда смотреть и насколько это будет возможно реализовать ?

Код javascript не прилагаю, т.к. там функции создания элементов, функция возврата рандомных чисел, то есть по сути, что касается вопроса - это готовый массив такого вида :

let array = [5,1,2,8,4,6,3,7]

Спасибо
  • Вопрос задан
  • 321 просмотр
Решения вопроса 2
sergiks
@sergiks Куратор тега JavaScript
♬♬
Как я понял, длина входного массива всегда на 1 меньше квадрата целого. Иначе не получится, дописав один ноль, получить квадратную матрицу.

Округляем в большую сторону квадратный корень из длины входного массива – это будет сторона квадратной матрицы. Проверяем, что длина всего на 1 отличается от квадрата.

Старый вариант в лоб

Дальше перебор строк и столбцов и наполнение.
function toMatrix(arr) {
  const len = arr.length;
  const side = Math.ceil( Math.sqrt(len));
  if( side * side - len !== 1) throw "Bad array length";
  let result = [], index;
  for(let row = 0; row < side; row++) {
    result.push([]);
    let currentRow = result[result.length - 1];
    for(let col = 0; col < side; col++) {
      index = side * row + col;
      if(index > len) break;
      if(index === len) {
        currentRow.push(0);
      } else {
        currentRow.push(arr[index]);
      }
    }
  }
  
  return result;
}


toMatrix([1,2,5]) // [[1,2],[5,0]]
toMatrix([1,2,3,4,5,6,7,8]) // [[1,2,3],[4,5,6],[7,8,0]]


Upd. незачем по одному копировать элементы, надо орудовать целыми строками )
function toMatrix(arr) {
  const len = arr.length;
  const side = Math.ceil( Math.sqrt(len));
  if( side * side - len !== 1) throw "Bad array length";
  let result = [];
  for(let row = 0; row < side; row++) {
    result.push( arr.slice(side * row, side * (row+1))); // выкусываем подряд строку, side элементов
  }
  result[side - 1].push(0); // в последниюю строку дописываем 0
  
  return result;
}

toMatrix([1,2,5]) // [[1,2],[5,0]]
toMatrix([1,2,3,4,5,6,7,8]) // [[1,2,3],[4,5,6],[7,8,0]]
Ответ написан
Stalker_RED
@Stalker_RED
function foo(input) {
  let size = Math.ceil(Math.sqrt(input.length))
  if (size*size - input.length !== 1) {
    return false     // or throw error?
  }
  return Array(size).fill(0)
    .map((row, rowNumber) => 
         Array(size).fill(0)
         .map((el, i) => 
              input[size * rowNumber + i] || 0
             )
        )
}
jsfiddle.net/zksrba85
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы