Skip to content

Instantly share code, notes, and snippets.

@bittersweetryan
Created May 6, 2014 21:31
Show Gist options
  • Save bittersweetryan/9fd6b9b1678a05c13c1b to your computer and use it in GitHub Desktop.
Save bittersweetryan/9fd6b9b1678a05c13c1b to your computer and use it in GitHub Desktop.
var Rx = require('rx');
var fs = require('fs');
var Observable = Rx.Observable;
// helper function for converting callback APIs to Observables
var toObservableFunction = Observable.fromNodeCallback;
// convert each callback function to a function that returns Observables
var readdir = toObservableFunction(fs.readdir)
var stat = toObservableFunction(fs.stat);
var path = process.argv[2];
// Now that the callback APIs are gone, we're off to the races with functional composition!
// get observable of array of files ex. {......["file1", "file2"]}
readdir(path).
flatMap(function(list) {
// convert array of files to Observable. ["file1","file2"] -> {...."file1"...."file2"}
return Observable.fromArray(list).
// call stat for each file and creates a tuple of file and time from the result.
// This creates a two dimensional collection, which is then flattened using merge (the default flattening strategy)
// {...."file1"...."file2"} ->
//
// -> {.....{file: "file1", mtime:23432}....{file:"file2", mtime:65465}}
flatMap(function(file) {
// call stat and create a tuple of file and time. "file1" -> {.....{file: "file1", mtime: 23432}}
return stat(path + "/" + file).
map(function(stat) {
return {file: file, mtime: stat.mtime};
}).
// if a call to stat fails, filter the file from the results by returning an empty stream.
// Remember, empty streams disappear during flatten operations.
onErrorResumeNext(Observable.empty());
});
}).
// convert observable of file and time pairs back to an array
// {...{file: "file1", mtime:23432}....{file:"file2", mtime:65465}} -> [{file: "file1", mtime:23432}, {file:"file2", mtime:65465}]
toArray().
map(function(fileDescriptors) {
// sort the array by time.
// [{file: "file2",mtime: 45384}, {file: "file1",mtime:23432}] -> [{file: "file1",mtime:23432}, {file: "file2",mtime: 45384}]
return fileDescriptors.
sort(function(left, right) {
return left.mtime - right.mtime
}).
// pull out just the file
// [{file: "file1",mtime:23432}, {file: "file2",mtime: 45384}] -> ["file1","file2"]
map(function(fileAndTime) {
return fileAndTime.file;
})
}).
forEach(
function(files) {
console.log(files);
},
function(e) {
console.log("Unable to get file list!" + e);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment