Задание: сделать так чтобы цвета не повторялись при выведении в консоль

Сделал так чтобы они не повторялись, но иногда проскакивает что в консоли пишет "цветов: 3", но показывает два.

function randomDiap(n,m) {
        return Math.floor(Math.random()*(m-n+1))+n;
}

function color(colorsCount) {
    var used={};
    var colors=[ '', 'красный', 'оранжевый', 'жёлтый', 'зелёный', 'голубой', 'синий', 'фиолетовый' ];
    console.log( 'цветов: ' + colorsCount );
    for ( var i=1; i<=colorsCount; i++ ) {
        var n=randomDiap(1,7);
        var colorName=colors[n];

        
        if (colorName in used){
            continue;
        }
        

        used[colorName]=true; 
        console.log( colorName );
    }
    
}

color(3);

Ответы (2 шт):

Автор решения: Zhihar

потому что логика кода неверная:

вот что у вас происходит:

  1. цикл по кол-ву требуемых цветов

  2. получаем случайно id цвета

  3. если цвет уже выбран, то переходим на новый этап цикла

в итоге происходит следующее:

допустим надо выбрать 3 цвета

выбрали 1 цвет: этап 1 цикла

выбрали 2 цвет: этап 2 цикла

попытались выбрать 3 цвет, но попали на занятый: этап 3 цикла
перешли на следующий этап цикла - а он уже закончился (потому что их всего 3)

поэтому вам надо или или

  1. или гонять в while пока не найдете неиспользуемый цвет

  2. или используемый цвет удалять из массива цветов

  3. или если цвет использован переходить по кругу пока не найдете неиспользованный

например:

function randomDiap(n,m) {
        return Math.floor(Math.random()*(m-n+1))+n;
}

function color(colorsCount) {
    let used = {};
    const colors=[ '', 'красный', 'оранжевый', 'жёлтый', 'зелёный', 'голубой', 'синий', 'фиолетовый' ];
    console.log( 'цветов: ' + colorsCount );
    
    for ( var i=1; i<=colorsCount; i++ ) {
        let colorName = ''
        while (true)
        {
          const n = randomDiap(1,7);
          colorName = colors[n];

          if (!(colorName in used))
              break;
        }

        used[colorName] = true; 
        console.log( colorName );
    }
    
}

color(3);

только надо учесть, что если цветов надо получить больше чем есть - цикл будет бесконечным, но для этого надо просто дополнительную проверку поставить

или так:

    function randomDiap(n,m) {
            return Math.floor(Math.random()*(m-n+1))+n;
    }

    function color(colorsCount) {
        const colors = [ '', 'красный', 'оранжевый', 'жёлтый', 'зелёный', 'голубой', 'синий', 'фиолетовый' ];
        console.log( 'цветов: ' + colorsCount );
        
        let local_colors = colors;

        for (let i = 0; i < colorsCount; i++) {
            const n = randomDiap(1, local_colors.length - 1);
            colorName = colors[n];

            local_colors.splice(n, 1); 
            console.log( colorName );
        }
    }

    color(3);

→ Ссылка
Автор решения: Aziz Umarov

Примерно так

function randomDiap(n,m) {
        return Math.floor(Math.random()*(m-n+1))+n;
}

function color(colorsCount) {
    let used=new Set();
    let colors=[ '', 'красный', 'оранжевый', 'жёлтый', 'зелёный', 'голубой', 'синий', 'фиолетовый' ];
    console.log( 'цветов: ' + colorsCount );
    for ( ;used.size < colorsCount; ) {
        var n=randomDiap(1,7);
        var colorName=colors[n];
        used.add(colorName);        
        
    }    
    return used;
}

let set1 = color(5);

for (const item of set1) {
  console.log(item);  
}

→ Ссылка