Проверка количества строк внутри массива, которые могут быть успешно преобразованы в число - PullRequest
1 голос
/ 22 февраля 2020

Вот описание задачи, над которой я работаю:

Напишите функцию countNumbers, которая принимает массив строк. Функция должна возвращать количество строк в массиве, которые могут быть успешно преобразованы в число. Например, строка «1» может быть успешно преобразована в число 1, но строка «привет» не может быть преобразована в число.

countNumbers(['a','b','3','awesome','4']); // 2
countNumbers(['32', '55', 'awesome', 'test', '100']); // 3
countNumbers([]); // 0
countNumbers(['4','1','0','NaN']); // 3
countNumbers(['7', '12', 'a', '', '6', '8', ' ']); // 4

Мой код:

function countNumbers(arr) {
    var count = 0;
    for (num in arr) {
        if (Number(arr[num]) !== NaN) {
            count++;
        }
    }
    return count;
}

Когда я консольный журнал (Number (arr [num]), я вижу NaN в консоли, однако, когда я сравниваю в l oop, переменная count не увеличивается, и я получаю возвращаемое значение, равное к длине массива.

Любые советы о том, что я могу делать неправильно или что я упустил, очень ценятся.

Ответы [ 8 ]

1 голос
/ 22 февраля 2020

Вы должны пройти от n до parseInt(), прежде чем переходить к isNaN(), в противном случае пробел будет оцениваться как 0 и засчитывается в сумму.

const isNum = (n) => !isNaN(parseInt(n));
const countNumbers = (arr) => arr.filter(isNum).length;

console.log(
  countNumbers(['a','b','3','awesome','4']), // 2
  countNumbers(['32', '55', 'awesome', 'test', '100']), // 3
  countNumbers([]), // 0
  countNumbers(['4','1','0','NaN']), // 3
  countNumbers(['7', '12', 'a', '', '6', '8', ' ']) // 4
);
1 голос
/ 22 февраля 2020

Отфильтруйте ваши массивы и получите их длины.

console.log(countNumbers(['a', 'b', '3', 'awesome', '4'])); // 2
console.log(countNumbers(['32', '55', 'awesome', 'test', '100'])); // 3
console.log(countNumbers([])); // 0
console.log(countNumbers(['4', '1', '0', 'NaN'])); // 3
console.log(countNumbers(['7', '12', 'a', '', '6', '8', ' '])); // 4

function countNumbers(arr) {
  return arr.filter(function(el) {
    return parseFloat(el) == el;
  }).length;
}
0 голосов
/ 22 февраля 2020

Другие решения тестирования isNaN(Number(character)) лучше. Я забыл про isNaN и написал это. Он работает медленнее и намного дольше.

function countNumbers(array) {
    let count = 0
    for (number of array) {
      if(typeof number === 'number') {
        count++
      } else if(typeof number === 'string') {
        let isNumber
        let numberCharacters = number.split('')
        const numberRegularExpression = new RegExp(/[0-9]/)
        for(character of numberCharacters) {
          if(numberRegularExpression.test(character) !== true) {
            isNumber = false
            break
          } else {
            isNumber = true
          }
        }
        if(isNumber === true) count++
      }
    }
    return count;
}
0 голосов
/ 22 февраля 2020

Вы можете использовать встроенную функцию isNaN ().
Просто замените оператор if следующим:

if (!isNaN(arr[num])){
0 голосов
/ 22 февраля 2020

Я думаю, с reduce это можно сделать

const countNumbers = arr => {
  return arr.reduce((acc, value) => isNaN(Number(value)) ? acc : acc + 1, 0)
}

const num = countNumbers(['a','b','3','awesome','4']);
console.log(num)
0 голосов
/ 22 февраля 2020

Вы можете отфильтровать с помощью isFinite и взять длину.

+'' -> 0
+' ' -> 0 

function countNumbers(array) {
    return array.filter(isFinite).length;
}

console.log(countNumbers(['a','b','3','awesome','4'])); // 2
console.log(countNumbers(['32', '55', 'awesome', 'test', '100'])); // 3
console.log(countNumbers([])); // 0
console.log(countNumbers(['4','1','0','NaN'])); // 3
console.log(countNumbers(['7', '12', 'a', '', '6', '8', ' '])); // 4, now 6

Если вам действительно нравятся только цифры, то вы можете проверить с помощью регулярного выражения.

function countNumbers(array) {
    return array.filter(RegExp.prototype.test, /^\d+$/).length;
}

console.log(countNumbers(['a','b','3','awesome','4'])); // 2
console.log(countNumbers(['32', '55', 'awesome', 'test', '100'])); // 3
console.log(countNumbers([])); // 0
console.log(countNumbers(['4','1','0','NaN'])); // 3
console.log(countNumbers(['7', '12', 'a', '', '6', '8', ' '])); // 4
0 голосов
/ 22 февраля 2020

Сократите это и оцените крайние случаи

console.log(countNumbers(['a','b','3','awesome','4'])); // 2
console.log(countNumbers(['32', '55', 'awesome', 'test', '100'])); // 3
console.log(countNumbers([])); // 0
console.log(countNumbers(['4','1','0','NaN'])); // 3
console.log(countNumbers(['7', '12', 'a', '', '6', '8', ' '])); // 4

function countNumbers(arrayStrings) {
  return arrayStrings.reduce((count, string) => isNaN(string) || string.trim() === '' ? count : count + 1, 0)
}
0 голосов
/ 22 февраля 2020

Две вещи прямо вверх:

  1. Петли.
  2. Переменные.

Когда вы решаете проблему с помощью циклов и переменных, у вас теперь есть два проблемы.

Удалите встроенный console.log, чтобы получить действительный счет как число.

Может быть более исчерпывающая или более умная проверка, чем эта, но вы можете легко изменить функцию isNum , не затрагивая другой код.

Без циклов, без переменных и разделения проблем - isNum logi c не смешивается с потоком управления.

Обновление: parseFloat проверка в ответе Алекса является проверкой, которую вы ищете.

const isNum = maybeNum => (typeof maybeNum === 'number' || typeof +maybeNum === 'number') &&  !isNaN(+maybeNum) && maybeNum != '' && maybeNum != ' '

const countNumbers = arr => console.log(arr.filter(isNum).length)
   

countNumbers(['a','b','3','awesome','4']); // 2
countNumbers(['32', '55', 'awesome', 'test', '100']); // 3
countNumbers([]); // 0
countNumbers(['4','1','0','NaN']); // 3
countNumbers(['7', '12', 'a', '', '6', '8', ' ']); // 4

Вот версия с более умной проверкой из ответа Алекса. Редактор не поддерживает объединение nulli sh, поэтому вместо parseFloat(maybeNum) ?? false вы должны сделать это, как будто это все еще 90-е годы:

parseFloat(maybeNum) || parseFloat(maybeNum) === 0

const isNum = maybeNum => 
  parseFloat(maybeNum) || 
  parseFloat(maybeNum) === 0

const countNumbers = arr => arr.filter(isNum).length
   
const test = arr => console.log(countNumbers(arr))

test(['a','b','3','awesome','4']); // 2
test(['32', '55', 'awesome', 'test', '100']); // 3
test([]); // 0
test(['4','1','0','NaN']); // 3
test(['7', '12', 'a', '', '6', '8', ' ']); // 4
...