Skip to content

Instantly share code, notes, and snippets.

@nimamehanian
Last active September 6, 2015 01:18
Show Gist options
  • Save nimamehanian/7c1438c39cf8aa72748d to your computer and use it in GitHub Desktop.
Save nimamehanian/7c1438c39cf8aa72748d to your computer and use it in GitHub Desktop.
Toy problem: SplitSort. Given an input string, render the space-separated entries across `n` columns, vertically, and in alphabetical order. (i.e., implement an elementary UNIX `ls -a` command)
// test strings
var str1 = 'the quick brown fox jumps over the lazy dog and this is probably the longest sentence you have ever come across because it just has so many words in it that it just runs on and on needlessly can you tell';
var str2 = 'Oh, what a harmony of abandonment and impulse, of unnatural and yet graceful postures, in that mystical language of limbs, freed from the weight of corporeal matter, marked quantity infused with new substantial form, as if the holy band were struck by an impetuous wind, breath of life, frenzy of delight, rejoicing song of praise miraculously transformed, from the sound that it was, into image.';
var rand = 'Oh, what a harmony of abandonment? and impulse!, of unnatural (and yet graceful) postures, in that mystical language of limbs, freed from the weight of corporeal matter, marked quantity infused with new substantial form; as if the holy band were struck by an impetuous wind, breath of life: frenzy of delight: rejoicing song of praise, miraculously transformed, from the sound that it was, into image.';
var files = '. .. .CFUserTextEncoding .DS_Store .Trash .avcd .babel.json .bash_history .bash_profile .bashrc .cache .config .cups .dbshell .divshot .firebaserc .gem .gemrc .ghc .gitconfig .heroku .irb-history .lein .local .m2 .mkshrc .mongorc.js .netrc .node-gyp .npm .oracle_jre_usage .pgpass .profile .psql_history .rnd .rvm .ssh .v8flags.3.28.73.mehanian.json .zlogin .zshrc Applications Creative%w%Cloud%w%Files Desktop Documents Downloads Library Movies Music Pictures Public dump.rdb';
// SplitSort
// @param {string} input: a string containing a space-separated list of entries
// @param {number} cols: the desired number of columns to render
// @param {boolean} lc: lower-case entries of input string, if true
var ls = listAll = splitSort = splort = function (input, cols, lc) {
// ensure cols is a positive integer; default to 3
cols = cols > 0 ? cols : 3;
// ensure input is a string and contains at least as many words as desired columns
if (cols > input.split(' ').length) {
throw new TypeError('The number of columns cannot exceed the number of available words.');
}
var
_format = function (str, lower) {
return str.split(' ').map(function (val) {
var len = val.length;
// lower-case the entry, if flag is passed
val = lower ? val.toLowerCase() : val;
// remove whitespace and , : ; ! " ? ( ) from entry
val = val.replace(/,|:|;|!|\"|\?|\(|\)|\s/g, '');
// add deliberate whitespace
val = val.replace(/%w%/g, ' ');
// remove trailing periods, unless entry is '.' or '..'
val = (len > 2 && val[len - 1] === '.') ? val.slice(0, len - 1) : val;
return val;
// sort alphabetically and drop any false values
}).sort().filter(function (val) { return !!val; });
},
_chunk = function (list, size) {
if (list.constructor.name !== 'Array') {
throw new TypeError('`list` must be an array.');
}
var i = 0, result = [];
while (i < list.length) {
result.push(list.slice(i, i += size));
}
return result;
},
// return the length of the longest string in a given column
_colWidth = function (column) {
if (column.constructor.name !== 'Array') {
throw new TypeError('`column` must be an array.');
}
return Math.max.apply(null, column.map(function (val) { return val.length; }));
},
_repeat = function (char, count) {
var result = '';
for (var i = 0; i < count; i++) {
result += char;
}
return result;
},
_align = function (col, row) {
if (matrix[col - 1] && matrix[col - 1][row]) {
return _repeat(' ', (_colWidth(matrix[col - 1]) - matrix[col - 1][row].length + 5));
} else {
throw new RangeError('The number of words in the input string do not evenly ' +
'split into ' + cols + ' columns. Try applying the function again with ' +
(cols - 1) + ' or ' + (cols + 1) + ' columns.');
}
},
// begin on a new line for proper alignment
result = '\n',
// split the data into an array
wordList = _format(input, lc),
// divide the number of words by the desired number of columns to yield column length (i.e., rows)
colLength = Math.ceil(wordList.length / cols),
// chunk into subarrays of colLength
matrix = _chunk(wordList, colLength);
// render (by row)
for (var r = 0; r < colLength; r++) {
// first column
result += matrix[0][r];
// remaining columns
for (var c = 1; c < cols; c++) {
// The padding is equal to the length of the longest word in the column,
// minus the length of the word, plus a five-space buffer (see `_align`)
result += _align(c, r);
result += (matrix[c] && matrix[c][r]) ? matrix[c][r] : '';
}
result += '\n';
}
// logging output because `return` statements do not render the newline (\n) character.
console.log(result);
// return result;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment