Starting with an input that accepts a file and a function that will eventually sort our string, ezString:
return (
<div>
<input type="file" onChange={e => showFile(e)}/>
{ezString ? getSortedArr() : null}
</div>
);
and a function to turn that file into text (with a 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])
}
and a sorting function
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
}
With these parts we have the full component:
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;
Areas for improvement:
- I'm terrible with regex, thus the terrible regex and the need to filter empty strings out of the
wordArray