【问题标题】:Read a text file in Javascript and count the number of each word用Javascript读取文本文件并计算每个单词的数量
【发布时间】:2023-12-21 12:01:01
【问题描述】:

我将这个答案留在这里,因为我花了大约一个多小时才解决问题,我希望能帮助其他寻找类似答案的人。

这个问题有几个部分都在单独的 SO 帖子中得到了回答:

  1. 在 javascript 中读取文本文件
  2. 解析文本以获取空格分隔的字符串,不包括特殊字符、制表符、换行符等。
  3. 统计每个单词的个数
  4. 按降序显示列表

【问题讨论】:

  • 有人建议这是 *.com/questions/18473326/… 的副本,但是,如果你想调用它,在 javascript 中读取文本文件会创建一个完全不同的“字符串”,而不是简单的 var 类型字符串并处理换行符、返回等。这也是一个 4 部分问题,其中链接的问题只是这四个部分之一的一小部分

标签: javascript reactjs file filereader


【解决方案1】:

从一个接受文件的输入和一个最终对我们的字符串进行排序的函数 ezString 开始:


return (
    <div>
      <input type="file" onChange={e => showFile(e)}/>
      {ezString ? getSortedArr() : null}
    </div>
  );

以及将该文件转换为文本的函数(使用 useState var ezString)

const [ezString, setEzString] = useState(null)

const showFile = async (e) => {
    e.preventDefault()
    const reader = new FileReader()
    reader.onload = async (e) => {
      const file = e.target.result
      const goodString = file.replaceAll(/\s\s+/g, ' ')
        .replaceAll(/(\r\n|\r|\n)/g, ' ')
        .replaceAll(/[^a-zA-Z ]/g, "").toLowerCase()
      setEzString(goodString);
    };
    reader.readAsText(e.target.files[0])
  }

还有一个排序功能

const getSortedArr = () => {
  let wordArray = ezString.split(' ').filter(n => n)
  let wordCount = {};
  for (let word of wordArray) {
    if (wordCount[word]) {
      wordCount[word] = wordCount[word] + 1
    } else {
      wordCount[word] = 1
    }
  }
  let sortedArr = Object.entries(wordCount).sort((a, b) => b[1] - a[1])
  return sortedArr ? sortedArr.map(arr => {
    return (
      <div key={arr[0]}>
        <p style={{fontSize: 16}}>{arr[0]}: {arr[1]}</p>
      </div>)
  }) : null
}

有了这些部分,我们就有了完整的组件:

import React, {useState} from 'react'

const WordCounter = () => {

  const [ezString, setEzString] = useState(null)

  const showFile = async (e) => {
    e.preventDefault()
    const reader = new FileReader()
    reader.onload = async (e) => {
      const file = e.target.result
      const goodString = file.replaceAll(/\s\s+/g, ' ')
        .replaceAll(/(\r\n|\r|\n)/g, ' ')
        .replaceAll(/[^a-zA-Z ]/g, "").toLowerCase()
      setEzString(goodString);
    };
    reader.readAsText(e.target.files[0])
  }


  const getSortedArr = () => {
    let wordArray = ezString.split(' ').filter(n => n)
    let wordCount = {};
    for (let word of wordArray) {
      if (wordCount[word]) {
        wordCount[word] = wordCount[word] + 1
      } else {
        wordCount[word] = 1
      }
    }
    let sortedArr = Object.entries(wordCount).sort((a, b) => b[1] - a[1])
    return sortedArr ? sortedArr.map(arr => {
      return (
        <div key={arr[0]}>
          <p style={{fontSize: 16}}>{arr[0]}: {arr[1]}</p>
        </div>)
    }) : null
  }



  return (
    <div className="App">
      <input type="file" onChange={e => showFile(e)}/>
      {ezString ? getSortedArr() : null}
    </div>
  );
}

export default WordCounter;

需要改进的地方:

  • 我不喜欢正则表达式,因此糟糕的正则表达式和需要从wordArray 中过滤出空字符串

【讨论】: