Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Генерирование массива с уникальными элементами. (https://javascript.ru/forum/dom-window/55701-generirovanie-massiva-s-unikalnymi-ehlementami.html)

Blondinka 10.05.2015 22:31

Генерирование массива с уникальными элементами.
 
Здравствуйте.
Пытаюсь вывести в цикле массив из 100 уникальных элементов.
Следующий код работает, но элементы повторяются (не уникальны).
var numbers = [];
for(var i = 0; i < 100; i++){
    var newItem = Math.floor(Math.random()*101);
    numbers.push(newItem);
}

document.write(numbers);


Этот не выводит ничего.
var numbers = [];
for(var i = 0; i < 100; i++){
    var newItem = Math.floor(Math.random()*101);
	if(numbers.length < 2){numbers.push(newItem);//Мало вероятно, что первые 2 элемента будут равны.
	}else{
        for(var j = 0; j < numbers.length; j++){
            if(newItem != numbers[j])numbers.push(newItem);
	}
    }
numbers.push(newItem);
}

document.write(numbers);

Подскажите, пожалуйста, почему второй код не работает. Где ошибка?

рони 10.05.2015 23:05

Blondinka,
массив заполняется в вашем случае по порядку без всякого random -- когда массив заполнен его перемешивают

Цитата:

Сообщение от Blondinka
Этот не выводит ничего.

строка 6
Цитата:

Сообщение от Blondinka
j < numbers.length

это условие бесконечного цикла

Leon-on12 10.05.2015 23:41

Предлагаю довольно странную проверку нового элемента на соответствие с уже записанными.
Ваше решение видимо короче, и менее грузно для процессора. Но разобраться в нём я не смог.
var numbers = [];
numbers[0] = Math.floor(Math.random()*101);
var check;
for(var i = 0; i < 100; i++){
	var newItem = Math.floor(Math.random()*101);
	check = 0;
	for(var n = 0; n < numbers.length; n++){
		if (newItem == numbers[n]){
			check++;
		}
	}
	if (check == 0){
		numbers.push(newItem);
	}
}

document.write(numbers);

Но возникает проблема в том что элементов не 100. У меня получилось в среднем 65 элементов. Если у нас просто 100 элементов надо расположить в произвольном порядке, то это задача чуть чуть другая, и решать её стоит чуть чуть по другому.
В смысле что у Вас 100 элементов и рандом даёт вам число от 100 до 1.
То есть у вас есть дискретный набор элементов которые надо перемешать.

Уточните пожалуйста задачу, в виду того что накручивать ещё костылей на моё решение для получения именно 100 элементов бессмысленно.
Поставьте перед собой правильную задачу. ;)

Blondinka 11.05.2015 00:09

Leon-on12,
Цитата:

Сообщение от Leon-on12 (Сообщение 370184)
Уточните пожалуйста задачу, в виду того что накручивать ещё костылей на моё решение для получения именно 100 элементов бессмысленно.

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

nerv_ 11.05.2015 00:24

Цитата:

Сообщение от Blondinka
document.write();

document.cookDinner();

Blondinka 11.05.2015 00:30

nerv_, document.write() - это плохо?

Leon-on12 11.05.2015 10:34

Для начала мы создаём массив.
var numbers = [];
for (var i=0; i < 100; i++){
	numbers[i] = (i+1);
}

Дальше мы последовательно берём каждый элемент, придумываем ему новое место, с помощью вашего генератора случайных чисел, и меняем его местами с элементом который стоит на новом месте.
var number1;
var number2;
var position;
for (var n=0; n<100; n++){
	number1 = numbers[n];
	position = Math.floor(Math.random()*100);
	number2 = numbers[position];
	numbers[position] = number1;
	numbers[n] = number2;
}

Это наглядный вариант. Его можно сократить убрав одну строчку и одну переменную.
Объединив код, сократив его, написав Ваше document.cookDinner(); И учитя что Вы любите объявлять переменные в коде, получаем:
var numbers = [];
for (var i=0; i < 100; i++){
	numbers[i] = (i+1);
}
for (var n=0; n<100; n++){
	var number1 = numbers[n];
	var position = Math.floor(Math.random()*100);
	numbers[n] = numbers[position];
	numbers[position] = number1;
}

document.write(numbers);

Так же Вы не уточнили какие именно элементы вам нужны. Так как в вашем примере генератор давал числа от 0 до 100, а это 101 элемент.

JsConAp 11.05.2015 11:19

Blondinka,
function getRandArr(arr, range) {
    var tmp = {};
    for (var i = 0; i < range; i++) {
        arr.push(Math.floor(Math.random() * (range + 1)));
    }

    for (var i = 0; i < arr.length; i++) {
        tmp[arr[i] + '.'] = 1;
    }
    if (Object.keys(tmp).length !== range) {
        for (var i = 0; i < arr.length; i++) {
            var newItem = Math.floor(Math.random() * (range + 1));
            tmp[(arr[i] + newItem) + '.'] = 1
        }
    }

    arr = Object.keys(tmp), count = arr.length;
    while (count > range) {
        count--;
        arr.splice(count, 1);
    }

    arr = arr.join('').split('.');
    arr.pop();
    return arr;
}
alert(getRandArr([], 100));

рони 11.05.2015 12:38

:write: на всякий случай
функция формирования массива с уникальными данными с заданной длиной и диапазоном

Blondinka 11.05.2015 15:43

Спасибо.


Часовой пояс GMT +3, время: 09:35.