Прежде всего: я абсолютный новичок в JavaScript и начал 2 недели назад, чтобы учиться много часов в день. Я использую сервер node.JS в GNU / Linux, и я попробовал множество вариантов, чтобы достичь цели. К сожалению, я застрял и не знаю, как продолжить.
У меня есть текстовый файл с пробелами и переводами строк, и файл содержит около 2000 строк. Я хочу прочитать этот текстовый файл в моей программе JavaScript, чтобы я мог использовать позже в качестве справочной таблицы. Я не уверен, нужно ли мне JSON преобразовать в строку для последующего использования, может быть, просто оставить его как объект / массив, который позже я смогу использовать для своей функции поиска. Я хочу вытащить из этого текстового файла только те строки, которые содержат символ «#» и использовать его в качестве разделителя. Все остальные строки можно игнорировать. Каждая строка представляет один набор данных, элемент, объект или все, что называется правильно. Конечная цель: пользователь запрашивает «Apple» , и он должен получить «-9.99» и «BTW» (например) в качестве ответа. Вот пример необработанного текстового файла:
Sugar# 1051# 331# BAD# 1.23# -4.56# -5.0# WWF#
N3T;
Apple# 551# 3815# F3W# 5.55# -9.99# -1.0# BTW#
BBC;
Berry# 19# 22# FF# 19.5# -12.34# 5.0# CYA#
T1K;
Он должен представлять 3 элемента, каждый из которых содержит 8 пар:
name: 'Sugar'
sec: 1051
ter: 331
wrd: 'BAD'
a: 1.23
b: -4.56
c: -5.0
spon: 'WWF'
name: 'Apple'
sec: 551
ter: 3815
wrd: 'F3W'
a: 5.55
b: -9.99
c: -1.0
spon: 'BTW'
name: 'Berry'
sec: 19
ter: 22
wrd: 'FF'
a: 19.5
b: -12.34
c: 5.0
spon: 'CYA'
В начале я пытался использовать fs.readFileSync , чтобы прочитать весь текстовый файл в виде строки, но безуспешно. Разочарован Я попробовал другой подход с readline , чтобы прочитать мой текстовый файл построчно и выполнить фильтрацию, потому что у меня сложилось впечатление, что этот метод более дружественный к памяти и позволяет читать даже очень большие файлы. Хотя я уверен, что 3000 строк - шутка :)
Это был мой код при приближении с readline:
const fs = require('fs');
const readline = require('readline');
function readAndFilter (source, data) {
var fields;
var obj = new Object;
var arr = new Array;
const readAndFilter = readline.createInterface({
input: fs.createReadStream('test.in'),
crlfDelay: Infinity
});
readAndFilter.on('line', (line) => {
if ( line.match( /#/ ) ) {
fields = line.split( '#' ).slice();
obj.name = fields[0].trim();
obj.sec = fields[1].trim();
obj.ter = fields[2].trim();
obj.wrd = fields[3].trim();
obj.a = fields[4].trim();
obj.b = fields[5].trim();
obj.c = fields[6].trim();
obj.spon = fields[7].trim();
console.log(obj);
// let jsonView = JSON.stringify(obj);
// arr.push(obj);
}
});
readAndFilter.on('close', function() {
return arr;
});
}
readAndFilter();
Это то, что выводит код (обратите внимание, что я настроил свой журнал консоли, добавив метку времени для каждого вывода строки):
2019-06-16 14:40:10 { name: 'Sugar',
sec: '1051',
ter: '331',
wrd: 'BAD',
a: '1.23',
b: '-4.56',
c: '-5.0',
spon: 'WWF' }
2019-06-16 14:40:10 { name: 'Apple',
sec: '551',
ter: '3815',
wrd: 'F3W',
a: '5.55',
b: '-9.99',
c: '-1.0',
spon: 'BTW' }
2019-06-16 14:40:10 { name: 'Berry',
sec: '19',
ter: '22',
wrd: 'FF',
a: '19.5',
b: '-12.34',
c: '5.0',
spon: 'CYA' }
поля данных выглядят хорошо, файл до сих пор обрабатывался правильно, но => объект "obj" будет содержать только последний набор данных (имя: Berry), потому что он перезаписывается после каждой построчной строки. Я дважды проверил, обрезав линию
console.log(obj);
из блока readAndFilter.on ('line', ... и вставить его в блок 'close':
[...]
readAndFilter.on('line', (line) => {
if ( line.match( /#/ ) ) {
fields = line.split( '#' ).slice();
obj.name = fields[0].trim();
obj.sec = fields[1].trim();
obj.ter = fields[2].trim();
obj.wrd = fields[3].trim();
obj.a = fields[4].trim();
obj.b = fields[5].trim();
obj.c = fields[6].trim();
obj.spon = fields[7].trim();
// let jsonView = JSON.stringify(obj);
// arr.push(obj);
}
});
readAndFilter.on('close', function() {
console.log(obj);
return arr;
});
[...]
полученная продукция:
{ name: 'Berry',
sec: '19',
ter: '22',
wrd: 'FF',
a: '19.5',
b: '-12.34',
c: '5.0',
spon: 'CYA' }
это не будет работать в качестве таблицы поиска, мне нужны все строки в массиве, чтобы я мог получить к ним доступ позже для процедуры поиска. Поэтому я попытался добавить каждый объект в один массив с помощью следующего кода:
[...]
readAndFilter.on('line', (line) => {
if ( line.match( /#/ ) ) {
fields = line.split( '#' ).slice();
obj.name = fields[0].trim();
obj.sec = fields[1].trim();
obj.ter = fields[2].trim();
obj.wrd = fields[3].trim();
obj.a = fields[4].trim();
obj.b = fields[5].trim();
obj.c = fields[6].trim();
obj.spon = fields[7].trim();
// let jsonView = JSON.stringify(obj);
arr.push(obj);
}
});
readAndFilter.on('close', function() {
console.log(arr);
return arr;
});
[...]
теперь я получаю массив с тремя объектами, но только последнее имя набора данных: снова отображается Берри
[ { name: 'Berry',
sec: '19',
ter: '22',
wrd: 'FF',
a: '19.5',
b: '-12.34',
c: '5.0',
spon: 'CYA' },
{ name: 'Berry',
sec: '19',
ter: '22',
wrd: 'FF',
a: '19.5',
b: '-12.34',
c: '5.0',
spon: 'CYA' },
{ name: 'Berry',
sec: '19',
ter: '22',
wrd: 'FF',
a: '19.5',
b: '-12.34',
c: '5.0',
spon: 'CYA' } ]
Я даже пробовал с concat и многими другими вариантами. Какого черта я делаю не так? Является ли мой подход, использующий метод readline / line-by-line совершенно неправильным, я должен вместо этого использовать fs.readFileSync? Я тоже попробовал, вот мой подход с fs.readFileSync:
function readAndFilter () {
var fields;
var obj = new Object;
var arr = new Array;
var data = fs.readFileSync('test.in', 'utf8').replace(/\r\n/g,'\n').split('\n').filter(/./.test, /\#/)
/*
if ( data.match( /#/ ) ) {
fields = data.split( '#' ).slice();
obj.name = fields[0].trim();
obj.cqz = fields[1].trim();
obj.itu = fields[2].trim();
obj.cont = fields[3].trim();
obj.lng = fields[4].trim();
obj.lat = fields[5].trim();
obj.tz = fields[6].trim();
obj.pfx = fields[7].trim();
};
*/
console.log(typeof data + "\n" + data);
}
Переменная data - это typeof object, как только я начинаю использовать .split ('\ n'), и, следовательно, я не могу использовать мое следующее условие if. Это терпит неудачу, потому что это будет работать только на строке. Может быть, я указываю полностью в неправильном направлении, и это намного проще? Конечная цель: я хочу проверить строку поиска, такую как «Apple» , по этой справочной таблице и получить соответствующие значения (имя, секунда, тер, b или любое из них).
Я действительно благодарен за любой полезный ответ или подсказку. Пожалуйста, будьте терпеливы со мной и честно сказали: я действительно много пробовал! Спасибо всем.