2014-03-02 6 views
1

Я пытаюсь привести простой текстовый парсер с Java на Javascript.Попробуйте реализовать простой текстовый парсер в javascript

Требование состоит в том, чтобы преобразовать данный CSV-файл в другой формат. Исходный файл перечисляет несколько значений в соответствии с одним идентификатором в определенных строках:

например:
11111; 12; 23; 23; ....
11111; 32; 12; 12; ....

Итак, первое значение - это Id, а остальные значения соответствуют этому Id. Теперь мне нужен тот же файл, что и все значения в соответствии с одним идентификатором в одной строке. Результат должен быть примерно таким:
11111; 12; 23; 23; 32; 12; 12; ....

я уже достиг этого с помощью простого класса Java:

public static void main(String[] args) throws Exception { 
     PrintWriter writer = new PrintWriter("t2_lines.csv", "UTF-8"); 
     BufferedReader br = new BufferedReader(new FileReader("t2.csv")); 

     String previousId=""; 
     String line; 

     while ((line = br.readLine()) != null) { 
      String [] words = line.split(";"); 
      String id = words[0]; 
      if (previousId.equals(id)){ 
       // the loop starts at 4 to cut out some unneded values 
       for(int i=4;i<words.length;i++) { 
        writer.print(words[i]+";"); 
       } 
      }else{ 
       writer.println(""); 
       for(String word : words) 
       writer.print(word+";"); 
       previousId = id; 
      } 
    } 
     br.close(); 
     writer.close(); 
    } 

и теперь я пытаюсь восстановить эту вещь в JavaScript, путем чтения в файле от клиента и представить результат в текстовое поле - но, к сожалению, не i've не осуществилось ничего в JavaScript, прежде чем ...

Это мой подход до сих пор:

window.onload = function() { 
var fileInput = document.getElementById('fileInput'); 
var origFileDisplayArea = document.getElementById('origFileDisplayArea'); 
var reformatFileDisplayArea= document.getElementById('reformatFileDisplayArea'); 

fileInput.addEventListener('change', function (e) { 
    var file = fileInput.files[0]; 
    var textType = /text.*/; 

    if (file.type.match(textType)) { 
     var reader = new FileReader(); 

     reader.readAsText(file); 

     reader.onload = function (e) { 
      var result = reader.result; 
      var table = parse(result); 
      origFileDisplayArea.innerText = table; 
     } 
    } else { 
     origFileDisplayArea.innerText = "File not supported!" 
    } 
}); 
} 

function parse(input) { 
var previousId = ""; 
var table = ""; 
if (typeof input !== "undefined") 
var lines = input.split("\n"); 
for (var i = 0; i <= lines.length; i++) { 
    var line = lines[i]; 
    if (typeof line !== "undefined") 
    var words = line.split(";"); 
    console.log("words length: ", words.length); 
    for (var j = 0; j <= words.length; j++) { 
     var word = words[j]; 

     if (typeof word !== "undefined") { 
      word.toString(); 
      var id = words[0]; 
      if (previousId === id) { 
       for (var jj = 4; jj <=words.length; jj++){ 
        console.log("jj: " + jj) 
        table += words[jj]+";"; 
       } 
      }else { 
       table += "\n"; 
       for (var word in words) { 
        table += word + ";"; 
        previousId = id; 
       } 
      } 
     } 
    } 


} 

return table; 
} 

но, к сожалению, i'm stucked п но с неопределенными значениями, и все это потребовало времени для запуска.

Так что любые подсказки/помощь были бы весьма полезны. Заранее спасибо

ответ

0

Да для FileReader Я не вижу способа избежать этого в этом контексте. Это не похоже на то, где у вас есть проблема.

Что касается parse, метода split может использовать много памяти, так что я бы не использовать его на весь файл, а for..in не предназначен для циклирующих через массив.

function parse(str_in) { 
    var i = -1, j = -1, 
     str_out = '', 
     last_id = '', 
     words; 
    str_in += '\n'; // not sure if necessary - let the last line pass `while` 
    // loop by seeking out the next new line 
    // i = old_index + 1 
    // j = next \n after old_index 
    // .slice(i, j) gives just the line 
    while (-1 !== (j = str_in.indexOf('\n', i = j + 1))) { 
     words = str_in.slice(i, j).split(';') 
     // loop words to trim whitespace here if you want 
     if (last_id === words[0]) // throw away first item if on the same id 
      words = words.slice(1); 
     else { 
      last_id = words[0]; 
      if (str_out.length) // lazy prevent first char newline 
       str_out += '\n'; 
     } 
     str_out += words.join(';'); // if you trimmed witespace, re-add here 
     // if you don't have a final semicolon, add it too 
    } 
    return str_out; 
} 

Теперь

parse('11111; 12; 23; 23 ;\n11111; 32; 12; 12 ;'); 
// "11111; 12; 23; 23 ; 32; 12; 12 ;" 

В качестве альтернативы, вы можете найти его проще писать методы, аналогичные тем, что вы привыкли в Java так что вы можете работать с минимальными изменениями, например,

function ReadLineGenerator(text) { 
    var start = -1, end = -1; 
    return function readLine() { 
     if (end < start) { 
      start = end = -1; 
      return null; 
     } 
     start = end + 1; 
     end = text.indexOf('\n', start); 
     if (end !== -1) 
      return text.slice(start, end); 
     else 
      return text.slice(start); 
    }; 
} 
// example usage 
var str = 'a\nb\nc', 
    f = ReadLineGenerator(str), 
    line; 
while (null !== (line = f())) 
    console.log(line); 
// "a", "b", "c" logged 
// line === null 
Смежные вопросы