Array.includes() всегда false, Array.indexOf() всегда -1 и Array.find() всегда не определены при обратном вызове экспресс-маршрутизатора

#javascript #arrays #node.js #express #ecmascript-6

#javascript #массивы #node.js #экспресс #ecmascript-6

Вопрос:

Я использовал fs.readFile() и fs.readFileSync() для чтения ‘words_alpha.txt ‘. Файл общедоступен по адресу:https://raw.githubusercontent.com/dwyl/english-words/master/words_alpha.txt

Даже если запрос test совпадает со словом в words_alpha.txt массиве строк файла, JSON всегда отвечает { includes: false, indexFound: false, found: undefined, forFound: false } следующим кодом JavaScript:

 var express = require('express');
var router = express.Router();
var fs = require('fs');

router.get('/test_validation', function(req, res, next) {
  const { test } = req.query;

  fs.readFile('words_alpha.txt', function(err, data) {
    const words = data.toString().split('n');

    const includes = words.includes(test);
    const indexFound = words.indexOf(test) > -1;
    const found = words.find(word => word === test);

    let forFound = false;
    for (i in words) {
      if (words[i] === test) {
        forFound = true;
        break;
      }
    }

    res.json({ includes, indexFound, found, forFound });
  });
});
  

Почему words.includes(test) , words.indexOf(test) и words.find(word => word === test) не удалось найти ни одного совпадения и даже с for (i in words) if (words[i] === test) ? Но ‘words_alpha.txt ‘ words могут регистрироваться один за другим с помощью for (i in words) console.log(words[i]) , но для завершения потребуется несколько секунд.

Комментарии:

1. Пожалуйста, опубликуйте содержимое words .

2. @adiga Слова регистрируются одно за другим от ‘a’, ‘aa’, ‘aaa’ до ‘zwitterionic’.

3. Я полагаю, причина, по которой вы не находите совпадения в своем наборе данных, заключается в том, что в вашем наборе данных нет совпадения. Вы уверены, что это слово существует? Это правильная заглавная буква? Использует ли он правильные символы (например, либо dies не содержит кириллицы е в отличие от латиницы е )? Вы уверены, что в вашем файле есть окончания строк Unix? Если у вас есть файл, написанный в Windows или совместимый с Windows, он будет иметь rn окончания строк в виде, а не просто n , поэтому разделение по последнему оставит вас с «someword r», который не соответствует «someword».

4. Только что проверил файл — в нем есть окончания строк Windows, поэтому вам нужно разделить на rn , а не на n . Или вы можете обрезать пробелы после разделения, если хотите, чтобы это работало для файлов любого типа. РЕДАКТИРОВАТЬ: или просто преобразовать окончания строк в файле, я полагаю.

5. @VLAZ Да, это было сумасшедшее дерьмо, я даже задавался вопросом, почему for (i in words) console.log(`^${words[i]}$`) выводил a ^word без $ . $ появится только в конце цикла. .split('rn') это единственное решение.

Ответ №1:

Проблема в том, что используемый вами файл имеет окончания строк в стиле Windows (CR LF или rn выраженные в виде символов), и вы разбиваете окончания строк в стиле Unix (LF или n ), что приводит к неправильному массиву слов:

 const stringOfWords = "applernbroccolirncarrot"; //windows line endings
console.log(stringOfWords)

const words = stringOfWords.split("n");
console.log(words);

console.log(words.includes("apple"))  

Или вы можете разделить только по окончаниям строк Windows, но вы рискуете, что код не будет работать для окончаний строк Unix:

 const stringOfWords = "applernbroccolirncarrot"; //windows line endings
console.log(stringOfWords)

const words = stringOfWords.split("rn");
console.log(words);

console.log(words.includes("apple"))  

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

 const stringOfWords = "applenbroccolincarrot"; //unix line endings
console.log(stringOfWords)

const words = stringOfWords.split("n");
console.log(words);

console.log(words.includes("apple"))  

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

 const stringOfWords = "applernbroccolirncarrot"; //windows line endings
console.log(stringOfWords)

const words = stringOfWords.split("n")
  .map(word => word.trim());
console.log(words);

console.log(words.includes("apple"))  

Или вы также можете разделить регулярным выражением для окончаний строк Windows или Unix:

 const stringOfWords = "applernbroccolirncarrot"; //windows line endings
console.log(stringOfWords)

const words = stringOfWords.split(/r?n/);
console.log(words);

console.log(words.includes("apple"))