Перемешать вложенные массивы в Javascript

Я пытаюсь отсортировать несколько массивов внутри массива (который также необходимо перетасовать). Упрощенный пример:

let toShuffle = [
[1, 2, 3, 4, 5],
[9, 8, 7, 6, 5],
[10, 67, 19 ,27]
...
];

const shuffled = shuffle(toShuffle);

// outout would look something like:
// [
//   [8, 6, 5, 7, 9],
//   [4, 3, 1, 5, 2],
//   [19, 26, 10, 67],
//   ...
// ]

Это должно быть гибким, поэтому любое количество массивов с любым количеством значений должно быть допустимым.

Вот что я пробовал:

function shuffle(a) {
  for (let e in a) {
    if (Array.isArray(a[e])) {
      a[e] = shuffle(a[e]);
    } else {
      a.splice(e, 1);
      a.splice(Math.floor(Math.random() * a.length), 0, a[e]);
    }
  }

  return a;
}

console.info("Shuffled: " + shuffle([
  [1, 2, 3, 4, 5],
  [5, 4, 3, 2, 1]
]))

Но это не работает, как задумано. Это более простой способ сделать это? Или мой код правильный и просто глючит.

Вы говорите it's not working as intended ... как выглядит предполагаемый результат?

Bravo 13.05.2022 02:14

Я не понимаю, что вы делаете в блоке else. Вы удаляете текущий элемент массива, но никогда не возвращаете его обратно.

Barmar 13.05.2022 02:14

@Barmar Я удаляю элемент e из массива, а затем добавляю его обратно в случайном месте.

KoderM 13.05.2022 02:15

Нет, ты не такой. Когда вы вырезаете элемент e, a[e] становится элементом, который раньше был a[e+1]. Итак, вы перемещаете это в случайное положение. Вы никогда не добавите обратно оригинал a[e].

Barmar 13.05.2022 02:17

Если вы хотите поменять местами два элемента массива, сделайте temp = a[e]; random = Math.floor(Math.random() * a.length); a[e] = a[random]; a[random] = temp;

Barmar 13.05.2022 02:19

Всегда ли он двумерный или это переменные уровни вложенности? Могут ли разные элементы быть вложены в разное количество?

Barmar 13.05.2022 02:21

Существует множество реализаций перетасовки по ставкам рыбака. (например, stackoverflow.com/a/46161940/294949) Заимствуйте один (который возвращает новый массив) и сопоставьте его

danh 13.05.2022 02:21
Поведение ключевого слова "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) для оценки ваших знаний,...
3
7
65
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ты почти понял. Проблема в том, что вы удаляете один элемент из массива вместо того, чтобы захватить удаленный элемент и поместить его в случайное положение:

let toShuffle = [
[1, 2, 3, 4, 5],
[9, 8, 7, 6, 5],
[10, 67, 19 ,27]
];

function shuffle(a) {
  a = [...a]; //clone array
  for (let e in a) {
    if (Array.isArray(a[e])) {
      a[e] = shuffle(a[e]);
    } else {
      a.splice(~~(Math.random() * a.length), 0, a.splice(e, 1)[0]);
    }
  }

  return a;
}

console.info(JSON.stringify(shuffle(toShuffle)))
console.info(JSON.stringify(toShuffle))

[РЕДАКТИРОВАТЬ] Исходный код не перетасовывал родительский массив, если вам нужно перетасовать все рекурсивно, вы можете использовать это:

let toShuffle = [
[1, 2, 3, 4, 5],
[9, 8, 7, 6, 5],
[10, 67, 19 ,27]
];

function shuffle(a) {
  a = a.map(i => Array.isArray(i) ? shuffle(i) : i); //clone array
  a.sort(i => ~~(Math.random() * 2) - 1); //shuffle
  return a;
}

console.info("shuffled", JSON.stringify(shuffle(toShuffle)))
console.info("original", JSON.stringify(toShuffle))

Этот код просто гениален. Как работает метод сортировки! С ума сошел.

KoderM 13.05.2022 02:41

Кроме того, только fwi. у вас есть 2 ненужные следующие строки. Вы можете просто сделать это: return a.map(i => Array.isArray(i) ? shuffle(i) : i).sort(i => ~~(Math.random() * 2) - 1);

KoderM 13.05.2022 02:44

О, конечно, это было для того, чтобы было легче понять, как это работает, он-лайнеры не подходят для образовательных целей ;)

vanowm 13.05.2022 02:46

Вот почему они так круто выглядят :) shuffle=a=>a.map(i=>Array.isArray(i)?shuffle(i):i).sort(i=>~‌​~(Math.random()*2)-1‌​);

KoderM 13.05.2022 02:47
Ответ принят как подходящий

Вы можете использовать Массив.от() для создания нового неглубокого копирования array, а затем перемешать Массив.прототип.сортировка() в сочетании с Math.random().

Код:

const toShuffle = [
  [1, 2, 3, 4, 5],
  [9, 8, 7, 6, 5],
  [10, 67, 19 ,27]
]

const shuffle = a => Array.from(a).sort(() => .5 - Math.random())
const result = toShuffle.map(shuffle)

console.info('Shuffled:', JSON.stringify(result))
console.info('To shuffle:', JSON.stringify(toShuffle))

Мне очень нравится этот ответ, он более простой. Array.from() это круто, просто прочитайте страницу MDN. Очень полезный.

KoderM 13.05.2022 06:41

За исключением того, что он не перемешивает сам массив toShuffle...

vanowm 13.05.2022 07:09

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