26.12.2015, 17:42
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,126
|
|
Создание массива с уникальными данными и в указанном диапазоне
функция заполняет массив уникальными данными в указанном диапазоне или перемешивает исходный, если диапазон не указан заполняет от нуля по порядку.
в трёх примерах ниже генерация происходит только пять раз.(исходная длина массива)
<script>
Array.prototype.randomShuffle = function(min,max) {
min = min || 0;
max = ++max || this.length;
var len = max - min;
max = len - this.length;
this.length = len;
for (var a = this.length-1; 0 <= a; a--) {
if(a < max) {break}
var b = Math.floor(Math.random() * a),
c = void 0 === this[b] ? (b + min) : this[b];
this[b] = void 0 === this[a] ? (a + min) : this[a];
this[a] = c
}
this.reverse();
this.length -= max;
return this
};
var arr = Array(5).randomShuffle();
document.write(arr+"<br>")
var arr = Array(5).randomShuffle(-100,100);
document.write(arr+"<br>")
var arr =[1,2,3,4,5].randomShuffle();
document.write(arr+"<br>")
document.write(["Собака след не взяла, Взяла", "но была убита убегающим", "след потеряла"].randomShuffle()+"<br>")
</script>
Последний раз редактировалось рони, 26.12.2015 в 19:35.
|
|
26.12.2015, 18:14
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,126
|
|
Deff,
не осилил
|
|
26.12.2015, 18:30
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,126
|
|
Deff,
ок, ничего не мешает вынести предложенный метод из прототипа в отдельную функцию, но меня твои аргументы не убедили,
по моему проще если нужно сделать arr.slice().shuffle() чем slice добавлять в функцию.
|
|
26.12.2015, 18:30
|
без статуса
|
|
Регистрация: 25.05.2012
Сообщений: 8,219
|
|
function indRand(a){
var out=[],n=a.length; a=a.slice(0);
while (n--){out.push(a.splice(Math.floor((n+1)*Math.random()),1)[0]);}
return out;
}
var tim = +new Date
var arr='1234567890'.split('');
n=1000000;
while (n--){
var b = indRand(arr);
}
alert((+new Date-tim)/1000);
Array.prototype.shuffle = function(min,max) {
min = min || 0;
max = ++max || this.length;
var len = max - min;
max = len - this.length;
this.length = len;
for (var a = this.length-1; 0 <= a; a--) {
if(a < max) {break}
var b = Math.floor(Math.random() * a),
c = void 0 === this[b] ? (b + min) : this[b];
this[b] = void 0 === this[a] ? (a + min) : this[a];
this[a] = c
}
this.reverse();
this.length -= max;
return this
};
var tim = +new Date
var arr='1234567890'.split('');
n=1000000;
while (n--){
var arr =arr.shuffle();
}
alert((+new Date-tim)/1000);
Твой Вариант значительно быстрее!
Гы, а на длинных массивах, длиной более 100, преимущество в 8 и более раз!
Последний раз редактировалось Deff, 26.12.2015 в 19:06.
|
|
26.12.2015, 19:22
|
без статуса
|
|
Регистрация: 25.05.2012
Сообщений: 8,219
|
|
Ксать подобная перестановка в математике обзывается
randomShuffle (Имхо более говорящее название, нативный перевод как: случайная перестановка из массива существующих)
==============================
Выложил бы на Хабре - Фишка весьма востребованная ( к примеру для массовой генерации паролей или ключей (Видел сотни вопросов про как сделать - всё примерно делали как в посте от Ruslan_xDD...
Упор делать на "быстрая!"
.
Последний раз редактировалось Deff, 26.12.2015 в 19:50.
|
|
26.12.2015, 19:34
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,126
|
|
Deff,
randomShuffle ок
Array.prototype.randomShuffle = function(c, b) {
c = c || 0;
b = ++b || this.length;
var a = b - c;
b = a - this.length;
this.length = a;
for (a = this.length - 1; 0 <= a && !(a < b); a--) {
var d = Math.floor(Math.random() * a),
e = void 0 === this[d] ? d + c : this[d];
this[d] = void 0 === this[a] ? a + c : this[a];
this[a] = e
}
this.reverse();
this.length -= b;
return this
};
alert(Array(5).randomShuffle())
Последний раз редактировалось рони, 26.12.2015 в 19:39.
|
|
26.12.2015, 23:43
|
без статуса
|
|
Регистрация: 25.05.2012
Сообщений: 8,219
|
|
Посмотри такой нюанс при max<2
var arr = Array(5).shuffle(-1,1);
Либо нун пояснить про диапазон c, b
Последний раз редактировалось Deff, 27.12.2015 в 04:09.
|
|
27.12.2015, 11:16
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,126
|
|
Deff,
защиты от дурака я не встраивал
|
|
27.12.2015, 12:07
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,126
|
|
чуть сократил ещё
Array.prototype.randomShuffle = function(c, b) {
c = c || 0;
b = ++b || this.length;
var a = b - c;
b = a - this.length;
this.length = a--;
for (; 0 <= a && !(a < b); a--) {
var d = Math.floor(Math.random() * a),
e = void 0 === this[d] ? d + c : this[d];
this[d] = void 0 === this[a] ? a + c : this[a];
this[a] = e
}
this.reverse();
this.length -= b;
return this
};
alert( Array(5).randomShuffle(-1,1))//заполнение пустого массива идёт на длину указанного диапазона от min до max
alert( Array(5).randomShuffle(-10,10))
|
|
27.12.2015, 13:24
|
без статуса
|
|
Регистрация: 25.05.2012
Сообщений: 8,219
|
|
рони, Т.е, если массив длинной 5, разность мин-мах диапазона проставленного в параметрах [a,b] вызова метода randomShuffle(a,b) должна быть не меньше пяти, для полного заполнения массива уникальными значениями ( Я задаю типовые вопросы, согласно любому представления нового скрипта на Хабре, вот я ап чём) Для тренировки
|
|
|
|