#javascript #arrays
#javascript #массивы
Вопрос:
Я новичок в Javascript и создаю игру с памятью, но, похоже, я не могу заставить этот код работать. То, что я пытаюсь сделать, это выбрать случайный элемент из моего ids
массива, а затем удалить его из этого массива, но впоследствии иметь возможность использовать это значение для присвоения его элементу в массиве cards. То, что я придумал до сих пор, это (обновлено):
const cards = document.querySelectorAll(".memory-card");
let ids = ["1", "1", "2", "2", "3", "3", "4", "4", "5", "5", "6", "6"];
function idHandler() {
let rand = Math.floor(Math.random() * ids.length);
let x = ids.splice(rand, 1)[0];
cards[x].setAttribute("id", x);
}
cards.forEach(mapIds);
Поскольку кто-то запросил html-элементы:
<div class="memory-card" id="1">
<img src="../assets/turned.png" class="front-face">
</div>
<div class="memory-card" id="1">
<img src="../assets/turned.png" class="front-face">
</div>
<div class="memory-card" id="2">
<img src="../assets/turned.png" class="front-face">
</div>
<div class="memory-card" id="2">
<img src="../assets/turned.png" class="front-face">
</div>
<div class="memory-card" id="3">
<img src="../assets/turned.png" class="front-face">
</div>
<div class="memory-card" id="3">
<img src="../assets/turned.png" class="front-face">
</div>
<div class="memory-card" id="4">
<img src="../assets/turned.png" class="front-face">
</div>
<div class="memory-card" id="4">
<img src="../assets/turned.png" class="front-face">
</div>
<div class="memory-card" id="5">
<img src="../assets/turned.png" class="front-face">
</div>
<div class="memory-card" id="5">
<img src="../assets/turned.png" class="front-face">
</div>
<div class="memory-card" id="6">
<img src="../assets/turned.png" class="front-face">
</div>
<div class="memory-card" id="6">
<img src="../assets/turned.png" class="front-face">
</div>
Комментарии:
1. Я не совсем понимаю, чего вы пытаетесь достичь, но вы смотрели на Splice для удаления случайного элемента из вашего массива? developer.mozilla.org/en-US/docs/Web/JavaScript/Reference /… ? При использовании
splice()
возвращаются удаленные элементы, поэтому вы можете сохранить их в переменной для последующего использования.let removedItem = ids.splice(randomValue, 1);
2. Array.prototype.pop удаляет последний элемент из массива, он не принимает никаких аргументов. То, что вы ищете, — это Array.prototype.splice , который удаляет элемент с определенным индексом.
3.
x
не всегда будет-1
с этим кодом, хотя это будет довольно большая часть времени. Это потому, что вы пытаетесь найти индекс в этом массиве случайно выбранного индекса из этого массива — индексы идут от 0 до 11 и"1"
присутствуют только"6"
в массиве. (Я также понятия не имею, почему вы храните их как строки, а не числа.)4. @RobinZigmond, на самом деле это не то, что происходит с кодом OP, проблема не в том, что значение x равно -1, проблема в том, что OP использует функцию Array.prototype.pop() . Эта функция всегда удаляет последнюю функцию из массива. Операционная система не знала этого, поэтому они предположили, что значение ‘x’ всегда равно -1, и именно поэтому последний элемент удалялся.
5. @Link — справедливая точка зрения, я только посмотрел, как
x
вычисляется, и поскольку это было явно неправильно, а также на что обращал внимание OP, я не видел необходимости смотреть дальше, прежде чем делать свой комментарий
Ответ №1:
Вы пытаетесь получить доступ к массиву неправильно,
function idHandler() {
let rand = Math.floor(Math.random() * ids.length);
let x = ids[rand]
ids.splice(rand,1) // can use this to remove an index from array
cards[rand].setAttribute("id", x); // values should already be strings as they are stored with "" marks
}
На самом деле вы можете пропустить шаг, если вам не нужно снова использовать переменную x
function idHandler() {
let rand = Math.floor(Math.random() * ids.length);
cards[rand].setAttribute("id", ids[rand]); // values should already be strings as they are stored with "" marks
ids.splice(rand,1) // can use this to remove an index from array
}
Ответ №2:
Я помогу вам понять ваш существующий код и где вы ошибаетесь с ним:
Вам не нужно получать ids.indexOf(rand) здесь, причина в том, что Math.Random будет генерировать число от 0 до 1, а затем вы умножаете его на ids.length . Это означает, что значение Math.random() будет начинаться с 0 и может доходить до ids.length . Поскольку ваш массив также основан на 0, вы можете напрямую использовать это значение и передать его в качестве параметра в функцию, которую вы будете использовать для разделения массива.
let rand = Math.floor(Math.random() * ids.length);
let x = ids.indexOf(rand.toString());
Функция Array.prototype.pop() всегда удаляет последний элемент
массива и возвращает его значение. Именно по этой причине вы всегда
получаете последний элемент.
ids.pop(ids[x]);
Вместо этого вы можете использовать Array.prototype.splice() . Что делает эта функция, так это то, что она принимает 2 аргумента — начальный индекс и конечный индекс, и изменяет массив, что означает, что он изменит ваш исходный массив. Кроме того, он возвращает значение удаленного элемента в новом массиве.
Я добавил пример фрагмента ниже, вы должны запустить его и увидеть результаты, также неплохо скопировать этот код в свою собственную среду разработки и попытаться отладить его с помощью console.log(), чтобы регистрировать значения на каждом шаге и видеть, что происходит, чтобы лучше понять. Не стесняйтесь задавать любые вопросы в комментариях под этим вопросом.
let ids = ["1", "1", "2", "2", "3", "3", "4", "4", "5", "5", "6", "6"];
function idHandler() {
const rand = Math.floor(Math.random() * ids.length);
const x = ids.splice(rand, 1)[0];
//[0] in above line to return the removed element instead of an array
//containing the element
console.log(x);
console.log(ids);
}
idHandler();
Комментарии:
1. Это очень помогло, но теперь он не может определить
cards[x]
, что очень странно, imo. Может быть, вы знаете, почему это так, но пока я постараюсь исправить это сам. Что я изменил, так это ` функция mapIds() { пусть rand = Math.floor(Math.random() * ids.length) пусть x = ids.indexOf(rand. toString()) console.log(x) пусть removedId = ids.splice(rand, 1) ids.splice(x, 1) console.log(ids) карточки[removedId[0]].setAttribute(«id», removedId[0]) } `2. можете ли вы попробовать сделать это и посмотреть, что будет напечатано на консоли — console.log(cards[x]);
3. переменная cards в соответствии с кодом, которым вы поделились в вопросе, представляет собой список узлов, в котором есть все узлы DOM, соответствующие классу ‘.memory-card’. Можете ли вы обновить вопрос и показать мне все элементы в вашем HTML с классом ‘.memory-card’, возможно, я смогу помочь с этой информацией.
4. иногда он выводит мой html div, а иногда просто не определен
5. Я понимаю, почему сейчас ничего не работает. Спасибо за помощь, и я сам загляну в списки узлов завтра, так как уже очень поздно, если я живу
Ответ №3:
Я думаю, что вы хотите splice
примерно так:
const cards = document.querySelectorAll(".memory-card");
let ids = ["1", "1", "2", "2", "3", "3", "4", "4", "5", "5", "6", "6"];
function idHandler() {
let rand = Math.floor(Math.random() * ids.length);
let x = ids.indexOf(rand.toString());
var removedIds = ids.splice(ids[x], 1);
cards[x].setAttribute("id", removedIds[0]);
}
cards.forEach(mapIds);
Функция splice() удаляет элементы из массива в заданной позиции и возвращает элементы в виде массива.
Дополнительная информация здесь: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice