Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Дублируются данные в цикле (https://javascript.ru/forum/misc/83821-dubliruyutsya-dannye-v-cikle.html)

Volonter 25.03.2022 11:25

Дублируются данные в цикле
 
Всем привет, столкнулся с проблемой и вообще не понимаю как решить. Есть функция, которая на вход принимает массив из чисел (но он может быть и пустым), и создает несколько наборов чисел (равное tcount)
function createTickets(mas) {
    let ticket = ''
    let tcount = document.getElementById('tcount').value
    for (t = 0; t < tcount; t++) {
        let numbers = []
        numbers.splice(0, numbers.length);
        numbers.length = 0;
        console.log(numbers)
        numbers = generate(mas);
        let ticketItem = ''
        numbers.forEach(n => {
            ticketItem += `<div class="ticket-item" data-select="${n}">${n}</div>`
        })
        ticket += `<div class="ticket-block">${ticketItem}</div>`
        numbers = []
        console.log(numbers)
    }

    ticketslist.insertAdjacentHTML('beforeend', ticket)
    numbers = []
    createTicketsButton.disabled = true
    ticket = ''
}

и функция generate(), которая генерирует массив случайных чисел с учетом входящего параметра(массив mas).
function generate(mas) {
    let arr = []
    arr.splice(0, arr.length);
    arr.length = 0;
    let max_number, i, unic;
    arr = (mas.length != 0) ? mas : []
    max_number = 6;
    while (arr.length < 6) {
        do {
            unic = true;
            a = Math.floor(Math.random() * 36) + 1;
            for (i = 0; i < arr.length; i++) {
                if (a == arr[i]) {
                    // такое число уже было
                    unic = false;
                    break;
                }
            }
        } while (!unic) // повторить генерацию числа
        arr.push(a);
    }
    return arr
}

Проблема в том, что если массив mas пустой, все работает как надо, а если в нем есть элементы - дублирует набор чисел в количестве равном tcount Подскажите пожалуйста, в чем ошибка? Заранее спасибо!

рони 25.03.2022 11:36

Volonter,
на всякий случай это
let numbers = []
        numbers.splice(0, numbers.length);
        numbers.length = 0;
        console.log(numbers)
        numbers = generate(mas);


равно этому
let numbers = generate(mas);


Цитата:

Сообщение от Volonter
// такое число уже было

не надо таких проверок, создайте массив нужных чисел, перемешайте и отрежьте нужный кусочек.

Volonter 25.03.2022 12:47

Цитата:

Сообщение от рони (Сообщение 544347)
Volonter,
на всякий случай это

равно этому
let numbers = generate(mas);



не надо таких проверок, создайте массив нужных чисел, перемешайте и отрежьте нужный кусочек.

Знаю, это я уж совсем от безысходности написал, да так в коде и оставил, но проблему это не решает

рони 25.03.2022 12:51

Volonter,
<!DOCTYPE html>
<html>
<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style type="text/css">
        .ticket-block {
            display: flex;
            width: 20em;
        }
        .ticket-item {
            text-align: center;
            font-size: 3em;
            border: 1px solid #000080;
            width: 100%;
        }
    </style>
</head>
<body>
    <input id="tcount" name="" type="number" min="1" max="6" value="2">
    <input id="createTicketsButton" name="" type="button" value="createTickets" onclick="createTickets()">
    <div id="ticketslist"></div>
    <script>
        function createTickets() {
            let tcount = +document.getElementById('tcount').value;
            let numbers = generate(36, 6);
            let ticket = ''
            for (t = 0; t < tcount; t++) {
                let ticketItem = '';
                numbers.next().value.forEach(n => {
                    ticketItem += `<div class="ticket-item" data-select="${n}">${n}</div>`
                })
                ticket += `<div class="ticket-block">${ticketItem}</div>`
            }
            ticketslist.insertAdjacentHTML('beforeend', ticket);
            createTicketsButton.disabled = true
        }
        function generate(length, limit) {
            let arr = Array(length);
            for (let i = 0; i < length; i++) {
                let k = Math.floor(Math.random() * length);
                let num = arr[k] || k + 1;
                arr[k] = arr[i] || i + 1;
                arr[i] = num;
            }
            return {
                [Symbol.iterator]() {
                    return this;
                },
                arr,
                next() {
                   
                    if (this.arr.length >= limit) {
                        return {
                            done: false,
                            value: this.arr.splice(0, limit)
                        };
                    } else {
                        return {
                            done: true
                        };
                    }
                }
            };
        }
    </script>
</body>
</html>

рони 25.03.2022 12:58

Volonter,
тоже самое, вариант попроще для понимания...
<!DOCTYPE html>
<html>
<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style type="text/css">
        .ticket-block {
            display: flex;
            width: 20em;
        }
        .ticket-item {
            text-align: center;
            font-size: 3em;
            border: 1px solid #000080;
            width: 100%;
        }
    </style>
</head>
<body>
    <input id="tcount" name="" type="number" min="1" max="6" value="2">
    <input id="createTicketsButton" name="" type="button" value="createTickets" onclick="createTickets()">
    <div id="ticketslist"></div>
    <script>
        function createTickets() {
            let tcount = +document.getElementById('tcount').value;
            let numbers = generate(36);
            let limit = 6;
            let ticket = ''
            for (t = 0; t < tcount; t++) {
                if(numbers.length < limit) break;
                let ticketItem = '';
                numbers.splice(0,6).forEach(n => {
                    ticketItem += `<div class="ticket-item" data-select="${n}">${n}</div>`
                })
                ticket += `<div class="ticket-block">${ticketItem}</div>`
            }
            ticketslist.insertAdjacentHTML('beforeend', ticket);
            createTicketsButton.disabled = true
        }
        function generate(length) {
            let arr = Array(length);
            for (let i = 0; i < length; i++) {
                let k = Math.floor(Math.random() * length);
                let num = arr[k] || k + 1;
                arr[k] = arr[i] || i + 1;
                arr[i] = num;
            }
            return arr
        }
    </script>
</body>
</html>

Volonter 25.03.2022 14:04

Спасибо, но в том то и фишка, что обе функции принимают массив mas, и функция generate возвращает новый массив, в который входят числа из массива mas. В моем случае, если mas пустой то все работает как надо, а если нет - то в каждой итерации дублируется первый возвращенный функцией generate массив

рони 25.03.2022 14:37

Volonter,
:-?


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