patternjavascriptModerate
Function to find longest word in a string
Viewed 0 times
functionwordfindlongeststring
Problem
Write a function called longest which will take a string of space-separated words and will return the longest one.
My code:
Running it with this test:
My code:
function longest(str) {
var words = arguments.split(" ");
var words_count = words.length;
var longest_word_length = 0;
for(var i = 0; i < words_count; i++){
if(longest_word_length < words[i].length){
longest_word_length = words[i].length;
}
}
return longest_word_length;
}Running it with this test:
describe("test for longest function functionality", function() {
it("should return correct output for normal strings", function() {
expect(longest("A")).toEqual("A");
expect(longest("I love Avatar")).toEqual("Avatar");
expect(longest("The stupidities of youth")).toEqual("stupidities");
});
it("should return correct output for gibberish", function() {
expect(longest("hgdydrxtfEq Rradsc tstsa taeWwwecfgdd")).toEqual("hgdydrxtfEq");
});
it("should work for sentences with numbers", function() {
expect(longest("This is a sentence with a number 7685838788")).toEqual("7685838788");
});
});Solution
Good on you for writing real tests.
Overall, the code seems fine as-is (edit: Actually, no. See David Harkness' comment on the question;
-
The JavaScript convention is to use
-
Splitting by
Also the whole thing can be made more functional (and use some ES6 syntax):
Another approach, much less functional, could be to use
The regex finds any run of non-whitespace character of length 1 or more. It's not terribly pretty, since
Overall, the code seems fine as-is (edit: Actually, no. See David Harkness' comment on the question;
arguments.split should be str.split) though I do have a few comments:-
The JavaScript convention is to use
camelCase for variable names - not snake_case.-
Splitting by
" " works, but a more comprehensive solution would be to split by /\s+/. That is, split by one or more whitespace characters. That way you avoid zero-length strings in the array if there are two spaces in a row, and it'll also split on newlines and other whitespace. And if you trim() the string first, you'll also avoid empty strings at the start/end if the input string has leading or trailing whitespace.Also the whole thing can be made more functional (and use some ES6 syntax):
function longest(string) {
return string
.trim()
.split(/\s+/)
.reduce((longest, word) => word.length > longest.length ? word : longest);
}reduce (aka "fold" in other languages), when given no 2nd argument, will use the first element - the first word - in the array as its initial memo. The callback then either reuses that word, or replaces it when it finds one that's longer. Whatever the memo is at the end is what gets returned.Another approach, much less functional, could be to use
String.replace as a "scan" function:function longest(string) {
var length = 0;
var longestWord = "";
string.replace(/\S+/g, (word) => {
if(word.length > length) {
length = word.length;
longestWord = word;
}
return ""; // for good measure; otherwise all words will be replaced with "undefined" in-memory
});
return longestWord;
}The regex finds any run of non-whitespace character of length 1 or more. It's not terribly pretty, since
replace isn't being used "as intended", really, and there are some closure side-effects. It doesn't have the memory consumption of the previous solution however (no array used to hold the split string).Code Snippets
function longest(string) {
return string
.trim()
.split(/\s+/)
.reduce((longest, word) => word.length > longest.length ? word : longest);
}function longest(string) {
var length = 0;
var longestWord = "";
string.replace(/\S+/g, (word) => {
if(word.length > length) {
length = word.length;
longestWord = word;
}
return ""; // for good measure; otherwise all words will be replaced with "undefined" in-memory
});
return longestWord;
}Context
StackExchange Code Review Q#160768, answer score: 12
Revisions (0)
No revisions yet.