У вас есть сочетание различных типов данных, присвоенных блок массива. Когда пользователь вводит значение, которое не является числовым, вы назначаете действительно вложенный массив одному из блоков , но не так, когда пользователь вводит действительный номер.
Из того, что я думаю, что вы делаете (игра в Судоку?), Это может быть предназначено: цифры являются известными значениями в сетке, вложенные массивы представляют собой список значений, которые все еще возможны в этой конкретной ячейке.
Но тогда во второй части вашего кода вы должны проверить, в каком из двух случаев вы находитесь, поскольку вы хотите удалить элементы массива только в том случае, если значение, которое вы ищете, действительно является массивом. Этот тест вы можете сделать с 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>
Обратите внимание, что существуют элементы, которые остаются block
null
. Я предполагаю, что вы намеревались это сделать: когда вы умножаете a
на 10 и сохраняете только 9 значений на «строку», всегда остается один индекс, который остается нетронутым.
Во-первых, я хотел бы сделать: 'console.log (блок [((а * 10) + с)])', чтобы увидеть, что это такое. Но, точнее, ошибка, которую вы получаете, указывает на то, что значение, вероятно, является объектом, а объекты не имеют метода 'indexOf' ... Строки, но вы, вероятно, не сохранили строку. Кроме того, помните, что ВСЕ данные, возвращаемые из 'prompt', возвращаются в виде строки. Даже если число было введено. –
номера не имеют метода indexOf() – dandavis
Вы не создаете многомерный массив, * block * - это просто простой массив. Первый цикл вставляет элементы с индексами от 0 до 99 способом, который может выполняться в одном цикле от 0 до 99. Только если вы введете отрицательное значение, элемент * block * будет массивом, скорее всего, вам понадобится 'typeof block [a] [b]! = "number". Но тогда вы получаете доступ к блоку [a * 10 + c] '. – RobG