ES6 получить случайные элементы из объекта без повтора - PullRequest
0 голосов
/ 16 сентября 2018

У меня есть функция, которая должна отображать случайные цвета, но без повторения цветов.

Значение, если синий выбран случайным образом, его нельзя выбрать снова.Конечно, это означает, что должно быть значение по умолчанию.Я думал об использовании оператора switch.

Вот мой текущий код:

const colors = {
      grey: '#BDC8D1',
      blue: '#0500FF',
      pink: '#FF00C7',
      orange: '#FF7A00'
    }

    const randomColor = () => {
      let keys = Object.keys(colors)
      return colors[keys[keys.length * Math.random() << 0]]
    }

Ответы [ 3 ]

0 голосов
/ 16 сентября 2018

Просто чтобы отличаться и использовать некоторое функциональное программирование:

const colors = {
      grey: '#BDC8D1',
      blue: '#0500FF',
      pink: '#FF00C7',
      orange: '#FF7A00'
    }


const randomIndex = arr => (Math.random() * arr.length) >> 0


const getColors = (keys = [], times = 0, colors = []) => {
  if (!keys.length || times <= 0) {
    return colors
  }

  const randIndex = randomIndex(keys)

  colors.push(keys[randIndex])
  keys.splice(randIndex, 1)
  times--


  return getColors(keys, times, colors)
}

// select 2 colors
console.log(getColors(Object.keys(colors), 2))

Примечание: было бы лучше, если бы вы не мутировали аргументы, т.е. keys.splice

Кроме того, вот метод .sort, который кто-то упомянул -классная идея.

Object.keys(colors).sort((a, b) => {
  const order = [ -1, 0, 1 ]
  return order[(Math.random() * 3) >> 0]
})
0 голосов
/ 16 сентября 2018

Вот фактическая реализация:

const colors = {
  grey: '#BDC8D1',
  blue: '#0500FF',
  pink: '#FF00C7',
  orange: '#FF7A00'
}



let keysArr = Object.keys(colors);
let keyArrLength = keysArr.length


for (let i = 0; i < keyArrLength; i++) {
  let el = keysArr[Math.floor(Math.random() * keysArr.length)];
  console.log(el);
  let index = keysArr.indexOf(el);
  keysArr.splice(index, 1);
}

Надеюсь, это полезно, если у вас есть какие-либо вопросы, вы можете оставить комментарий;).

0 голосов
/ 16 сентября 2018

Вы можете «потреблять» массив допустимых значений для возврата.Под потреблением я подразумеваю удаление их из массива.

Например:

// List of all valid values (those that can be returned)
const colors = [ 'red', 'green', 'blue' ];

// The default color (when all others have been "consumed")
const defaultColor = 'black'; 

// The function that returns a random color
const getRandomColor = () => {
    // At least we return a color
    let color = defaultColor;

    // If all colors were previously consumed, we won't need
    // to pick one randomly
    if (colors.length > 0) {
        // We select randomly an index from the colors array
        const index = Math.floor(colors.length * Math.random());

        // We store the color to return
        color = colors[index];

        // We remove it from the array
        colors.splice(index, 1);
    }
    
    return color;
};

console.log(getRandomColor());
console.log(getRandomColor());
console.log(getRandomColor());
console.log(getRandomColor());
console.log(getRandomColor());
console.log(getRandomColor());

Очевидная проблема с этим решением состоит в том, что вы не можете использовать свою функцию несколько раз.Лучшим решением было бы создание итератора.Каждый раз, когда какая-то часть вашего приложения должна генерировать случайную серию цветов, вы создаете новый итератор и используете его метод next для получения нового значения.Проверьте следующее:

// The default color (when all others have been "consumed")
const defaultColor = 'black'; 

const RandomColorIterator = () => {
    // List of all valid values (those that can be returned)
    const colors = [ 'red', 'green', 'blue' ];
    
    return {
        next: () => {
            // At least we return a color
            let color = defaultColor;

            // If all colors were previously consumed, we won't need
            // to pick one randomly
            if (colors.length > 0) {
                // We select randomly an index from the colors array
                const index = Math.floor(colors.length * Math.random());

                // We store the color to return
                color = colors[index];

                // We remove it from the array
                colors.splice(index, 1);
            }

            return color;
        },
    };
};

const iterator1 = RandomColorIterator();
console.log('1:', iterator1.next());
console.log('1:', iterator1.next());
console.log('1:', iterator1.next());
console.log('1:', iterator1.next());
console.log('1:', iterator1.next());
console.log('1:', iterator1.next());
console.log('1:', iterator1.next());
console.log('1:', iterator1.next());
console.log('1:', iterator1.next());

const iterator2 = RandomColorIterator();
console.log('2:', iterator2.next());
console.log('2:', iterator2.next());
console.log('2:', iterator2.next());
console.log('2:', iterator2.next());
console.log('2:', iterator2.next());
console.log('2:', iterator2.next());
console.log('2:', iterator2.next());
console.log('2:', iterator2.next());

Я использовал функцию стрелки для получения прибыли из родительской области.Это позволяет получить доступ к colors для каждого звонка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...