2016-11-12 3 views
1

Я пытаюсь найти индекс числа в 2d массив, но консоль выдаетмногомерный массив IndexOf не работает JS

Uncaught TypeError:. Блок [((а * 10) + с)] IndexOf не является функцией

Я думаю, что это имеет какое-то отношение к способу доступа к элементу массива, но, похоже, не может найти проблему.

Вот код.

var block = []; 
var temp; 
var del; 

for(var a = 0;a < 9;a++){ 
    for(var b = 0;b < 9;b++){ 
     temp = parseInt(prompt("enter element number " + b + " of row number " + a)); 
     console.log(temp); 
     if(temp>0){ 
      block[a*10+b] = temp; 
     }else{ 
      block[a*10+b] = [1,2,3,4,5,6,7,8,9]; 
     } 
//  console.log(block[a*10+b]); 
    } 
} 
for(var a = 0;a < 9;a++){ 
    for(var b = 0;b < 9;b++){ 
     if(typeof(block[a][b]) == "number"){ 
      for(var c = 0;c < 9;c++){ 
       if(c != b){ 
        del = block[a*10+c].indexOf(b); 
        block[a*10+c].splice(del,1); 
       } 
      } 

     } 

    } 
} 
+2

Во-первых, я хотел бы сделать: 'console.log (блок [((а * 10) + с)])', чтобы увидеть, что это такое. Но, точнее, ошибка, которую вы получаете, указывает на то, что значение, вероятно, является объектом, а объекты не имеют метода 'indexOf' ... Строки, но вы, вероятно, не сохранили строку. Кроме того, помните, что ВСЕ данные, возвращаемые из 'prompt', возвращаются в виде строки. Даже если число было введено. –

+0

номера не имеют метода indexOf() – dandavis

+1

Вы не создаете многомерный массив, * block * - это просто простой массив. Первый цикл вставляет элементы с индексами от 0 до 99 способом, который может выполняться в одном цикле от 0 до 99. Только если вы введете отрицательное значение, элемент * block * будет массивом, скорее всего, вам понадобится 'typeof block [a] [b]! = "number". Но тогда вы получаете доступ к блоку [a * 10 + c] '. – RobG

ответ

0

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

Из того, что я думаю, что вы делаете (игра в Судоку?), Это может быть предназначено: цифры являются известными значениями в сетке, вложенные массивы представляют собой список значений, которые все еще возможны в этой конкретной ячейке.

Но тогда во второй части вашего кода вы должны проверить, в каком из двух случаев вы находитесь, поскольку вы хотите удалить элементы массива только в том случае, если значение, которое вы ищете, действительно является массивом. Этот тест вы можете сделать с Array.isArray().

Есть также некоторые другие вопросы, во второй части вашего скрипта:

  • Выражение block[a][b] не согласуется с тем, как вы заполнили этот массив: он должен быть block[a*10+b] быть последовательным.
  • b в .indexOf(b) неверно: вы не ищите это значение, но для block[a*10+b].
  • splice() всегда выполняется, даже если indexOf возвращен -1. Это приводит к нежелательному эффекту, поскольку если первый аргумент splice() отрицательный, индекс действительно подсчитывается с конца массива, и все же элемент удаляется из массива. Этого не должно произойти: вы должны выполнить только splice, если результат indexOf неотрицателен.

Ниже я поставил рабочую версию, но для того, чтобы избежать почти бесконечных приглашений, я представил этот фрагмент с текстовым, где вы можете ввести полный 9x9 сетка на одном дыхании, а затем нажмите кнопку, чтобы начать выполнение кода:

document.querySelector('button').onclick = function() { 
 
    var block = []; 
 
    var temp; 
 
    var del; 
 
    var text = document.querySelector('textarea').value.replace(/\s+/g, ''); 
 
    for(var a = 0;a < 9;a++){ 
 
     for(var b = 0;b < 9;b++){ 
 
      temp = parseInt(text[a*9+b]); // <-- get char from text area 
 
      if(temp>0){ 
 
       block[a*10+b] = temp; 
 
      }else{ 
 
       block[a*10+b] = [1,2,3,4,5,6,7,8,9]; 
 
      } 
 
     } 
 
    } 
 
    for(var a = 0;a < 9;a++){ 
 
     for(var b = 0;b < 9;b++){ 
 
      var num = block[a*10+b]; // <-- get content, fix the index issue 
 
      if(typeof num == "number"){ 
 
       for(var c = 0;c < 9;c++){ 
 
        if(c != b && Array.isArray(block[a*10+c])){ //<-- add array-test 
 
         del = block[a*10+c].indexOf(num); // <-- not b, but num 
 
         if (del > -1) // <-- only splice when found 
 
          block[a*10+c].splice(del,1); 
 
        } 
 
       } 
 
      } 
 
     } 
 
    } 
 
    document.querySelector('pre').textContent = 'block='+ JSON.stringify(block); 
 
};
<textarea rows=9> 
 
53..7.... 
 
6..195... 
 
.98....6. 
 
8...6...3 
 
4..8.3..1 
 
7...2...6 
 
.6....28. 
 
...419..5 
 
....8..79 
 
</textarea> 
 
<button>Process</button> 
 
<pre></pre>

Обратите внимание, что существуют элементы, которые остаются blocknull. Я предполагаю, что вы намеревались это сделать: когда вы умножаете a на 10 и сохраняете только 9 значений на «строку», всегда остается один индекс, который остается нетронутым.

+0

Большое спасибо! Я просто новичок в программировании, поэтому сделал большие ошибки. И да, это решатель судоку. –

+0

Вы wecome ;-) – trincot

0

Я не просматривал ваш второй цикл for, но вы можете попробовать применить аналогичную логику там, как в фрагменте, который я предоставил. Проблема заключается в том, что вам необходимо создать временный массив внутри внешнего цикла for над значениями a (но НЕ внутри внутреннего, вложенного цикла for с значениями b).Внутри цикла for для значений b, тогда вам нужно push что-то во временный массив (который я назвал temp). Затем, за пределами цикла bfor, но перед следующей итерацией a надавите на этот временной массив temp на массив block. Таким образом, вы создадите 2D-массив.

var block = []; 
 
var del; 
 

 
for(var a = 0; a < 9; a++) { 
 
    let temp = []; 
 
    for(var b = 0; b < 9; b++) { 
 
    let num = parseInt(prompt(`Enter element ${b} of row ${a}:`)); 
 
    if (num > 0) { 
 
     temp.push(num); 
 
    } else { 
 
     // block[a*10+b] = [1,2,3,4,5,6,7,8,9]; 
 
     temp.push(b); 
 
    } 
 
    } 
 
    block.push(temp); 
 
}

Смежные вопросы