Skip to content

Instantly share code, notes, and snippets.

@jaksm
Created February 14, 2020 21:02
Show Gist options
  • Save jaksm/19a1ce71db3e80ded398a84a42932c88 to your computer and use it in GitHub Desktop.
Save jaksm/19a1ce71db3e80ded398a84a42932c88 to your computer and use it in GitHub Desktop.
csv-pair-splitter
import * as fs from "fs";
/*
* Apstrahovanje logike
* "pakovanje funckionalnosti tako da moze kasnije da se poziva sa promenjenim parametrima"
* */
function split({ inputPath, outputFolder, fileNameSuffix, inputSeparator, outputSeparator }) {
// read file contents
fs.readFile(inputPath, 'utf8', (err: any, data: string) => {
// csv files are read like string, so split them up into rows by new line ("\n") and remove "\r" from each row
const rows = data.split("\n").map(row => row.substring(0, row.length - 1));
/*
* Parsiranje redova - proces u kome dovodimo input podatke u pogodnu formu za obradu
* */
// grupisani redovi (po dva reda)
// u pocetku je to prazan niz
const grouped: string[][] = [];
// treba nam temporary niz u kome cemo da cuvamo dva reda, i kad se napune dva reda da ga ispraznimo i tako sve dok ne obradimo sve redove iz CSV fajla
let group: string[] = [];
// for petljom prolazimo kroz svaki red procitan iz CSV fajla
for (let i = 0; i < rows.length; i++) {
// izdvajamo red koji je trenutno u petlji
const row = rows[i];
// pridruzujemo trenutni red temporary nizu odozgo
group.push(row)
// ako ima ostatka pri deljenju sa 2, odnosno index trenutnog reda je neparan
if (i % 2 !== 0) {
// pridruzujemo temporary niz grupisanim redovima posto smo napravili grupu od dva reda
grouped.push(group)
// praznimo temporary niz kako bi ova radnja mogla da se ponavlja dok god ima neobradjenih redova
group = [];
}
}
/*
* Formatiranje podataka pred upis u fajlove
* Cilj je da ih tako formatiramo da nam upis bude sto laksi
* U ovom slucaju nam treba nacin da lako dohvatimo fileName sa ekstenzijom i sadrzaj fajla pri upisu
* */
// .map je petlja koja prolazi kroz svake grupe koje smo napravili
const results = grouped.map(group => {
// izdvajamo prvi deo prvog reda u grupi (sve pre prvog pajpa)
const firstChunk = group[0].split(inputSeparator)[0];
// sklapamo prvi deo u string sa sufiksom i ekstenzijom
const fileName = `${firstChunk}-${fileNameSuffix}.csv`;
// transformisemo sadrzaj fajla u pocetno stanje
const contents = group.map((row) => `${row}\r\n`).join('');
return { fileName, contents: contents.split(inputSeparator).join(outputSeparator) }
})
/*
* Upis
* prolazimo kroz sve rezultate
* */
results.forEach(result => {
// upisujemo sadrzaj fajla na pravu putanju koristeci fileName
fs.writeFileSync(`${outputFolder}/${result.fileName}`, result.contents)
})
});
}
// Pozivanje funkcije sa svim parametrima
split({
inputPath: './input/flexi-frame.csv',
outputFolder: './output/flexiframe',
fileNameSuffix: 'flexi',
inputSeparator: ',',
outputSeparator: '|'
});
// TODO: Razmisli o tome da li su nam svi parametri neophodni (npr. outputSeparator, fileNameSuffix) i implementiraj if statement ako je ovaj parametar opcion?
// TODO: Razmisli o greskama koje mogu da se dogode i implementiraj error handling. Sta bi program trebalo da radi ako ne postoji input putanja ili nije validna? Da li program treba da kreira foldere output putanja nije validna?
// TODO: Trenutni program kaze samo "done!" na kraju, da li je to dovoljno komunikacije sa userom? Sta da smo imali 10000000000 redova i da ceo proces traje 1 min?
console.log("done!")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment