Я не могу получить индекс строки в массиве и удалить его | javascript

#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