Задать вопрос

Как выбрать несколько случайных неповторяющихся элементов?

Здравствуйте. Задача в следующем: Есть список. По клику на элемент списка нужно вывести три случайных элемента этого списка: а) чтобы элемент по которому кликнули - не выводился, б) чтобы один и тот же элемент не выводился многократно и c) если в списке всего три элемента - все три и выводятся.

Помогите, пожалуйста, всю голову сломал. Пока получилось Вот что. Выводятся три рандомных элемента и не выводится тот, на котором сработал клик. Правда и то, не всегда правильно - иногда выводится вообще один элемент вместо трех. Ну и не могу придумать, как избежать повторения индексов.
  • Вопрос задан
  • 655 просмотров
Подписаться 1 Оценить 4 комментария
Решения вопроса 3
evgeniy8705
@evgeniy8705
Повелитель вселенной
0xD34F
@0xD34F Куратор тега JavaScript
Откуда, куда, что и в каком количестве надо копировать:

const sourceSelector = '#a';
const targetSelector = '#b';
const itemSelector = 'li';
const count = 3;

Вспомогательная функция - вырезание из массива случайного элемента:

const random = arr => arr.splice(Math.random() * arr.length | 0, 1)[0];

Копируем:

$(sourceSelector).on('click', itemSelector, function() {
  const items = $(this).siblings().clone().get();
  $(targetSelector).html([...Array(count)].map(random.bind(null, items)));
});

// или

const source = document.querySelector(sourceSelector);
const target = document.querySelector(targetSelector);
source.addEventListener('click', ({ target: t }) => {
  if (t = t.closest(itemSelector)) {
    const items = [...source.querySelectorAll(itemSelector)].filter(n => n !== t);
    target.innerHTML = '';
    target.append(...Array.from(
      { length: Math.min(items.length, count) },
      () => random(items).cloneNode(true)
    ));
  }
});

Похоже на то, что вам надо?

UPD. Как-то сразу не заметил:

если в списке всего три элемента - все три и выводятся

Сначала получаем всё, если кликнутый не нужен, вырезаем его:

const items = $(itemSelector, sourceSelector).clone().get();
if (items.length > count) {
  items.splice($(this).index(), 1);
}

// или

const items = [...source.querySelectorAll(itemSelector)];
if (items.length > count) {
  items.splice(items.indexOf(t), 1);
}
Ответ написан
@Ridz
добавил в вариант 0xD34F если в списке всего три элемента - все три и выводятся.
и убрал лишний массив
$(function() {
function getRandomElems($el) {
    $("#b").html("");
    var $li = $el.siblings();
    $li.length < 3 && ($li = $li.add($el));
    $li = $li.get();
    for (var i = 0; i < 3; i++) {
        var rand = (Math.random() * $li.length) | 0;
        $($li.splice(rand,1)).clone().appendTo($("#b"));
    }
}

$("#a").on('click', 'li', function() {
    getRandomElems($(this));
});
});
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

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