2015-12-08 3 views
1

Вот мой код:Возврат массива Javascript добавляет двойные кавычки?

function iLoveThree (array) { 
    var threes = []; 
    var x; 
    for (x in array) { 
    if (x % 3 == 0) { 
     threes.push(x) 
    } 
    } 
    return threes 
} 

Когда я передать массив [1,2,3,4,5,6,7,8,9] Я получаю следующее:

Function returned 
["0","3","6"] 
instead of 
[3,6,9] 

Мой вопрос: откуда берутся эти двойные кавычки?

+1

Лучше не использовать 'для ... в' для перебора массивов. – Oriol

ответ

0

for..in петля делает не цикла по элементам массива, он перебирает индексы массива.Так:

var arr = ["a", "b", "c"] 
for (x in arr) console.log(x); 

Вы получите строковые ключи ["0", "1", "2"]

Вы можете исправить свой код, заменив свой цикл с родной for цикла:

for (var x = 0; x < array.length; x++) { 
    if (array[i] % 3 == 0) 
     threes.push(array[i]); 
} 
+0

Это сработало! Спасибо. У меня был почти такой же точный код раньше, но я использовал массив [count] вместо переменной. Это то, что @void сказал в своем комментарии выше. –

+0

Crockford рекомендовал 'array.forEach' над традиционным циклом' for'. Просто FYI. –

-1

Если вы читаете документацию for...in, вы поймете, что вы подталкиваете к threes в индексы (называемых также ключей) а не значения, так как переменная x представляет индекс, поэтому значение должно быть доступ к array[x].

function iLoveThree (array) { 
    var threes = []; 

    for (var x in array) { 
    if (array[x] % 3 == 0) { 
     threes.push(array[x]) 
    } 
    } 
    return threes 
} 

Есть несколько способов для достижения этой цели, лучше один является использованием filter, но путь был уже пояснялись кем-то еще, поэтому я буду использовать экзотическую реализацию с использованием reduce

[1, 2, 3, 4, 5, 6, 7, 8, 9].reduce(function(acc, e){return e % 3 == 0 ? acc.concat(e) : acc}, []) 

Выходы 3, 6, 9

+1

Это все еще дает ему неправильный ответ. Он хочет, чтобы значения делились на три, а не индексы. – TbWill4321

+0

@ TbWill4321 Решенный, я редактировал его, когда вы прокомментировали! Но спасибо –

0

Так что в основном в x in arrayx - это индекс, а не значение массива. Потому что в любом случае 0 не находится в массиве, но ваша функция также возвращает его. Вы должны вместо этого получить доступ к данным с помощью array[x]

Существуют различные подходы, один из них использует .filter

function iLoveThree(array){ 
    return array.filter(function(x){ 
     return (x%3==0?1:0); 
    }); 
} 

Или

function iLoveThree (array) { 
    var threes = []; 
    var x; 
    [].forEach.call(array, function(x){ 
    if (x % 3 == 0) { 
     threes.push(x) 
    } 
    } 
    return threes 
} 
0

Вы используете петлю for..in, которая дает вам ключи в объекте или в этом случае и в массиве. Ключи всегда являются строками. Вместо этого вы хотите использовать стандартный цикл for.

for (var i = 0; i < array.length; i++) { 
    var x = array[i]; 
    if (x % 3 === 0) { 
    threes.push(x); 
    } 
} 

Или, если вы хотите использовать более функциональный подход, вы могли бы использовать Array.prototype.filter.

return array.filter(function(x) { 
    return x % 3 === 0; 
}); 
0

кажется, что вы нажатие индексов, а не фактические значения, выполните следующие действия:

function iLoveThree(array) { 
    var threes = []; 
    var x; 
    for (x in array) { 
     if (((x-2) % 3) == 0) { 
      threes.push(array[x]) 
     } 
    } 
    return threes; 
} 

Другой вариант, короче, это:

function iLoveThree(arr) { 
    var threes = []; 
    for (var i = 2; i < arr.length; i = i + 3) { 
     threes.push(arr[i]); 
    }; 
    return threes; 
} 

, если вы знакомы с обратным вызовом/предикатные на основе циклов, вы могли бы сделать вещи еще короче путем фильтрации массива, вместо создания нового:

function iLoveThree(arr) { 
    return arr.filter(function(x) { 
     return (x % 3) == 0; 
    }); 
} 
2

for...in - это плохой способ итерации индексов массива. Лучше использовать filter:

[1,2,3,4,5,6,7,8,9].filter(function(x) { 
    return x % 3 == 0; 
}); // [3, 6, 9] 
+0

Можете ли вы сказать мне, почему «за ... в» плохо? Дуглас Крокфорд также не рекомендует его, но я не могу вспомнить, почему. –

+1

@RahulDesai См. [Почему используется «для ... в» с итерацией массива такая плохая идея?] (Http://stackoverflow.com/q/500504/1529630). В этом случае 'for ... in' будет проблематичным, поскольку он не гарантирует никакого порядка, поэтому результат будет зависеть от реализации. – Oriol

0

Не ответ на ваш вопрос прямо, но вот хороший способ, чтобы вытащить все кратные 3 из массива чисел:

[1,2,3,4,5,6,7,8,9].filter(item => item % 3 === 0)

+0

Обратите внимание, что функции стрелок не работают в большинстве браузеров без транслирования. – TbWill4321

+1

@ TbWill4321 Вопрос не задал версию JS. –

0

Перед тем, как прочитать ответ ниже, пожалуйста, прочитайте: Why is using “for…in” with array iteration such a bad idea? (спасибо @Oriol за эту ссылку.)

Douglas Crockford также обескуражил использование for..in. Вместо этого он рекомендует использовать array.forEach.

function iLoveThree (array) { 
 
    var threes = []; 
 

 
    array.forEach(function(item, i){ // use forEach, 'item' is the actual value and 'i' is the index 
 
    if (item % 3 === 0) { 
 
     threes.push(item); // you missed ; here 
 
    } 
 
    }); 
 

 
    return threes; // you missed ; here 
 
} 
 

 
console.log(iLoveThree([1,2,3,4,5,6,7,8,9]));

Читайте: Array.prototype.forEach() | MDN

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