Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Случайное значение без повторений в диапазоне от min до max (https://javascript.ru/forum/misc/46034-sluchajjnoe-znachenie-bez-povtorenijj-v-diapazone-ot-min-do-max.html)

рони 26.03.2014 14:23

Aetae,
это понятно - ещёб я знал как это правильно назвать :(
так пойдёт?
основное каждый следующий неповторит предыдущий - цепочка бесконечна - нет лишних генераций -- все значения выпадают равномерно .
<!DOCTYPE HTML>

<html>

<head>
  <title>Untitled</title>
</head>

<body>
<script>
function rund(len, min) {
        function shuffle(arr) {
            for (var i = len = arr.length, elem; elem = arr[--i];) {
                var num = Math.floor(Math.random() * len);
                    arr[i] = arr[num];
                    arr[num] = elem;
            }
            return arr
        } //функция для перемешивания массива
        var base = [], // основной массив
            temp = [], // запасной массив
            i ;
        for (i = 0; i < len; i++) base[i] = i + min; // формирование значений основного массива[1, 2, 3, 4, 5]
        shuffle(base); // первый раз перемешали основной массив [4, 3, 2, 1, 5]
        return function () {
            var elem = base.shift(); // берём первый элемент основного массива
            temp.push(elem); //добавляем в запасной
            1 == base.length && (shuffle(temp), base = base.concat(temp), temp = []);
            // если в основном остался 1 элемент, перемешиваем запасной и добавляем к основному, очищаем запасной 
            return elem 
        }
    };

 var len = 5,  // длина массива
     min = 1,  // значение 1 элемента массива
     z = rund(len,min),
     i;

 for (i = 0; i < 40; i++) {
     document.write(z()+' '); //для примера
 }
</script>

</body>
</html>

ponyspy 26.03.2014 17:57

рони,
Большое спасибо за разъяснение и понятное именование переменных. У вашего алгоритма действительно очень равномерное распределение, это важно. Однако у него есть один недостаток, для вызова рандома требуется создавать глобальный объект, можно ли как-то решить эту проблему?

Sweet 26.03.2014 18:05

Цитата:

Сообщение от ponyspy
для вызова рандома требуется создавать глобальный объект, можно ли как-то решить эту проблему?

Создавай его в локальной области видимости:
!function () {
 var len = 5,  // длина массива
     min = 1,  // значение 1 элемента массива
     z = rund(len,min),
     i;
 
 for (i = 0; i < 40; i++) {
     document.write(z()+' '); //для примера
 }
} ();

рони 26.03.2014 18:11

Цитата:

Сообщение от ponyspy
Однако у него есть один недостаток, для вызова рандома требуется создавать глобальный объект, можно ли как-то решить эту проблему?

непонял ничего -- смотрите пост 6 и скажите где там глобальность?

ponyspy 26.03.2014 19:24

рони,
Действительно некорректно сформулировал задачу. Необходимо изолировать функцию рандома от внешнего окружения.

Сейчас вызов выглядит вот так:

var roundRandom = rund(600, 200);

function generatePoster () {
  var rand_radius = roundRandom();
}


А если потребуется переопределить границы рандома внутри обработчика?

рони 26.03.2014 19:40

ponyspy,
примерно так )))
var roundRandom = rund(600, 200);

function generatePoster () {
  if(сегодня среда && и мы ещё не меняли !generatePoster.смена )  {roundRandom = rund(100, 10);!generatePoster.смена= true}
  var rand_radius = roundRandom();
}

рони 26.03.2014 20:17

ponyspy,
или так меняйте
<!DOCTYPE HTML>
<html>

<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  <style type="text/css">
  .round{background:#FFA500;width:0px;height:0px;padding:8px;border-radius:4px}
  .image{width:100%;height:100%}
  .hide{display:none}
  </style>
  <script>
  $(function (){
   $('#test').click(generatePoster);
    function rund(e, f) {
        function d(b) {
            for (var a = b.length - 1; 0 < a; a--) {
                var c = Math.floor(Math.random() * (a + 1)),
                    d = b[c];b[c] = b[a];b[a] = d }
            return b}
        var a = [],c = [];
        for (i = 0; i < e; i++) a[i] = i + f;d(a);
        return function () {
            var b = a.shift();c.push(b);
            1 == a.length && (d(c), a = a.concat(c), c = []);
            return b
        }
    };
    var hide_items = $('.hide').size();
	var rand_items = rund(hide_items, 0);
	var rand_radius = rund(400, 200);
    $('#size').click(changeSize);
    function changeSize()
    {
       var min = +$('#min').val()||0,max = +$('#max').val()||0;
       if (min > max) return;
       rand_radius = rund(max-min, min)
    }
    function generatePoster () {
        //var item = rand_items();
        var radius  = rand_radius(); //item и radius использовать если нужны одинаковые значения
		var atr = $('.hide').eq(rand_items()).attr('src');
		$('.image').attr('src', atr);
		//$('.main_poster_cal').hide().eq(rand_items()).show();
		$('.round').css("background-color", "#"+Math.ceil(Math.random()*16777214).toString(16))
        .animate({
			width: radius,
			height: radius
		}, {duration: 400, queue: false})
	}
})

  </script>
</head>

<body>
  <input id="test" type="button" value="generate">  min<input id="min" value="50" >max<input id="max" value="150"><input id="size" type="button" value="size">
  <div class="round">
  <img class="image"  src="" alt="">
  </div>
  <img class="hide"  src="http://cache.foxsaver.com/thumbnails/2009/06/17/1410246630t.jpg" alt="">
  <img class="hide"  src="http://mindfulreiki.co.uk/wp-content/uploads/2012/12/flower-300x300.png" alt="">
  <img class="hide"  src="http://www.fragrantica.ru/images/avatariru/t.38016.jpg" alt="">
  <img class="hide"  src="http://www.birdz.sk/uc/av/e/c/ec9fecaceb74d24679b73295e80f10ca.jpg" alt="">
  <img class="hide"  src="http://cs304505.vk.me/v304505947/5fe0/uWP57ucJ5cM.jpg" alt="">
  <img class="hide"  src="http://s018.radikal.ru/i519/1202/62/8856baf46906.jpg" alt="">
</body>

</html>


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