简体   繁体   中英

Find longest word in Javascript array

So I'm working on this codility coding challenge and I cannot get the code to work for all inputs, particularly large ones. The rules for this are here .

To summarize, I need each word in the string to be tested for: alpha-numeric characters only, even number of letters, and odd number of digits.

For the sample input - "test 5 a0A pass007 ?xy1", this solution effectively ignores "test" (it has an even number of digits, 0 digits) and "?xy1" (special character, ?). From the leftover options, it chooses pass007 as the longest word and returns 7 (length of word).

I start by splitting the string into separate words and then generating if statements to check if each word in my new array meets the requirements, isAlpha, isAlphaEven (remainder 0 for even # of letters), isNumeric (remainder 1 for odd numbers).

Any idea what I am doing wrong? Thanks much! :)

 // you can write to stdout for debugging purposes, 
 // e.g. console.log('this is a debug message');

function solution(S) {
// write your code in JavaScript (Node.js 8.9.4)
// you can write to stdout for debugging purposes, 
// e.g. console.log('this is a debug message');
// write your code in JavaScript (Node.js 8.9.4)
var words = S.split(" "); 
var isAlpha = /^[0-9a-zA-z]*$/; 
var isAlphaEven = /^[a-zA-Z]/;
var isNumeric = /^[0-9]/; 
var maxLength = -1;

for(var i = 0; i <= words.length - 1; i++) { 
    if(words[i].match(isAlpha) 
    && words[i].replace(isAlphaEven, '').length % 2 == 0
    && words[i].replace(isNumeric, '').length % 2 == 1
    || words[i].match(isNumeric)
    ) {
        maxLength = Math.max(maxLength, words[i].length);
        //console.log(words[i], maxLength);
    }
}

 return maxLength; 
}

One problem is that the patterns

var isAlphaEven = /^[a-zA-Z]/;
var isNumeric = /^[0-9]/; 

can only match characters at the start of the string: ^ anchors to the beginning. It also isn't a global match, so it'll only replace one character. Another problem is that you're replacing the matches with the empty string, rather than testing the number of matches. To test the number of matches, use .match instead, with the global flag, and check the length of the resulting array (or null if there are no matches):

 function solution(S) { // write your code in JavaScript (Node.js 8.9.4) // you can write to stdout for debugging purposes, // eg console.log('this is a debug message'); // write your code in JavaScript (Node.js 8.9.4) var words = S.split(" "); var allAlphaNumeric = /^[\\da-z]*$/i; var alpha = /[az]/gi; var numeric = /\\d/g; var maxLength = -1; for (var i = 0; i <= words.length - 1; i++) { if (words[i].match(allAlphaNumeric) && (words[i].match(alpha) || []).length % 2 == 0 && (words[i].match(numeric) || []).length % 2 == 1 ) { maxLength = Math.max(maxLength, words[i].length); } } return maxLength; } console.log(solution("test 5 a0A pass007 ?xy1")); 

Note that you can use the case-insensitive flag instead of repeating a-zA-Z , and you can use \\d instead of [0-9] if you wish.

While you could use .replace to figure out the number of matches, it'd be convoluted: you'd have to replace everything that doesn't match with the empty string, which would make the code's intent somewhat confusing.

You already have the answer why your approach didn't work as expected.
So I thought I could add a slightly different approach with multiple .filter() steps

 function findLongestWord(input) { const isAlphaNumericOnly = /^[a-z0-9]+$/i; const numbersOnly = /\\d/g; const alphaOnly = /[az]/gi; const validWords = input.split(/\\s/) .filter(word => isAlphaNumericOnly.test(word)) .filter(word => (word.match(numbersOnly) || []).length % 2 === 1) .filter(word => (word.match(alphaOnly) || []).length % 2 === 0) .sort((a, b) => b.length - a.length); return { word: validWords[0], length: validWords[0] ? validWords[0].length : -1 }; } console.log(findLongestWord("test 5 a0A pass007 ?xy1")); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM