字母数我对Coderbyte的JavaScript挑战

时间:2015-12-07 09:33:44

标签: javascript regex function loops object

我已经解决了这个问题好几个小时了,尽我所能,尽我所能解决这个挑战的新手javaScript能力,但我无法弄清楚到底出了什么问题。我一直在“http://jsfiddle.net/6n8apjze/14/

获得”意外的非法入境许可证

和“TypeError:无法读取null的属性'length':http://goo.gl/LIz89F

我认为问题是howManyRepeat变量。我不明白为什么我得到它无法读取null的长度,当明确单词是来自str的一个词...

我明白了:

word.toLowerCase().split("").sort().join("").match(/([.])\1+/g).length

...这里:Get duplicate characters count in a string

挑战:
使用JavaScript语言,使用函数LetterCountI(str)取str 传递参数并返回最大数量的第一个单词 重复的信件。例如:“今天,这是有史以来最伟大的一天!”应该回来 最大的,因为它有2个e(和2个t),并且它之前也是 有2个e。如果没有重复字母的单词返回-1。言语会 被空格隔开。

function LetterCountI(str){
  var wordsAndAmount={};
  var mostRepeatLetters="-1";
  var words=str.split(" ");

     words.forEach(function(word){
       // returns value of how many repeated letters in word.
       var howManyRepeat=word.toLowerCase().split("").sort().join("").match(/([.])\1+/g).length;       
        // if there are repeats(at least one value).
        if(howManyRepeat !== null || howManyRepeat !== 0){ 
          wordsAndAmount[word] = howManyRepeat;
        }else{
         // if no words have repeats will return -1 after for in loop.
         wordsAndAmount[word] = -1; 
         }
     });

     // word is the key, wordsAndAmount[word] is the value of word.
     for(var word in wordsAndAmount){ 
        // if two words have same # of repeats pick the one before it.
        if(wordsAndAmount[word]===mostRepeatLetters){ 
          mostRepeatLetters=mostRepeatLetters;
        }else if(wordsAndAmount[word]<mostRepeatLetters){ 
          mostRepeatLetters=mostRepeatLetters;
        }else if(wordsAndAmount[word]>mostRepeatLetters){
          mostRepeatLetters=word;
        }
      } 

  return mostRepeatLetters;
}

// TESTS
console.log("-----");   
console.log(LetterCountI("Today, is the greatest day ever!"));   
console.log(LetterCountI("Hello apple pie"));    
console.log(LetterCountI("No words"));    

非常感谢任何指导。谢谢!! ^ ____ ^

3 个答案:

答案 0 :(得分:1)

以下是工作代码段:

&#13;
&#13;
/*
Using the JavaScript language, have the function LetterCountI(str) take the str 
parameter being passed and return the first word with the greatest number of 
repeated letters. For example: "Today, is the greatest day ever!" should return 
greatest because it has 2 e's (and 2 t's) and it comes before ever which also 
has 2 e's. If there are no words with repeating letters return -1. Words will 
be separated by spaces. 

console.log(LetterCountI("Today, is the greatest day ever!") === "greatest");
console.log(LetterCountI("Hello apple pie") === "Hello");
console.log(LetterCountI("No words") === -1);

Tips: 
This is an interesting problem. What we can do is turn the string to lower case using String.toLowerCase, and then split on "", so we get an array of characters.

We will then sort it with Array.sort. After it has been sorted, we will join it using Array.join. We can then make use of the regex /(.)\1+/g which essentially means match a letter and subsequent letters if it's the same.

When we use String.match with the stated regex, we will get an Array, whose length is the answer. Also used some try...catch to return 0 in case match returns null and results in TypeError.

/(.)\1+/g with the match method will return a value of letters that appear one after the other. Without sort(), this wouldn't work.
*/

function LetterCountI(str){
  var wordsAndAmount={};
	var mostRepeatLetters="";
  var words=str.split(" ");
  
  words.forEach(function(word){
    
      var howManyRepeat=word.toLowerCase().split("").sort().join("").match(/(.)\1+/g);
      
			if(howManyRepeat !== null && howManyRepeat !== 0){ // if there are repeats(at least one value)..
    	 	 	 wordsAndAmount[word] = howManyRepeat;
			  } else{
           wordsAndAmount[word] = -1; // if no words have repeats will return -1 after for in loop.
        }
  });
  
//  console.log(wordsAndAmount);
	for(var word in wordsAndAmount){ // word is the key, wordsAndAmount[word] is the value of word.
   // console.log("Key = " + word);
   // console.log("val = " + wordsAndAmount[word]);
    	if(wordsAndAmount[word].length>mostRepeatLetters.length){ //if two words have same # of repeats pick the one before it.
        mostRepeatLetters=word; 
  		}
  }	
  return mostRepeatLetters ? mostRepeatLetters :  -1;
}

// TESTS
console.log("-----");
console.log(LetterCountI("Today, is the greatest day ever!"));
console.log(LetterCountI("Hello apple pie"));
console.log(LetterCountI("No words"));

/*
split into words

var wordsAndAmount={};
var mostRepeatLetters=0;
  
  
loop through words
	Check if words has repeated letters, if so
  	Push amount into object
    Like wordsAndAmount[word[i]]= a number
  If no repeated letters...no else.
  
Loop through objects
  Compare new words amount of repeated letters with mostRepeatLetters replacing whoever has more.
  In the end return the result of the word having most repeated letters
  If all words have no repeated letters return -1, ie. 
*/
&#13;
&#13;
&#13;

所做的更改:

  • [.]变为.[.]与文字句点符号匹配,不是任何字符,而是换行符
  • 在代码末尾添加了结束*/(最后一个评论区块未关闭,从而导致UNEXPECTED TOKEN ILLEGAL
  • if(howManyRepeat !== null || howManyRepeat !== 0)应替换为if(howManyRepeat !== null && howManyRepeat !== 0),否则null会测试0的相等性并导致TypeError: Cannot read property 'length' of null"问题。请注意,由于匹配的结果可能为null,因此无法使用.match(/(.)\1+/g).length,这也会导致出现TypeError。
  • 获取具有最大重复次数的第一个条目的算法是错误的,因为第一个if块允许后续条目作为正确结果输出(不是第一个,而是具有相同重复的最后一个条目)实际输出)
  • 如果-1为空,则可以返回
  • mostRepeatLetters

答案 1 :(得分:1)

希望你不介意我改写这段代码。我的代码可能效率不高。 这是一个片段

function findGreatest() {
   // ipField is input field
    var getString = document.getElementById('ipField').value.toLowerCase();
    var finalArray = [];
    var strArray = [];
    var tempArray = [];
    strArray = (getString.split(" "));
    // Take only those words which has repeated letter
    for (var i = 0, j = strArray.length; i < j; i++) {
        if ((/([a-zA-Z]).*?\1/).test(strArray[i])) {
            tempArray.push(strArray[i]);
        }
    }
    if (tempArray.length == 0) {       // If no word with repeated Character
        console.log('No such Word');
        return -1;
    } else {                 // If array has words with repeated character
        for (var x = 0, y = tempArray.length; x < y; x++) {
            var m = findRepWord(tempArray[x]);  // Find number of repeated character in it
            finalArray.push({
                name: tempArray[x], 
                repeat: m
            })
        }
      // Sort this array to get word with largest repeated chars
        finalArray.sort(function(z, a) {
            return a.repeat - z.repeat
        })
        document.getElementById('repWord').textContent=finalArray[0].name;
    }
}

// Function to find the word which as highest repeated character(s)
    function findRepWord(str) {
        try {
            return str.match(/(.)\1+/g).length;
        } catch (e) {
            return 0;
        } // if TypeError
    }

这是DEMO

答案 2 :(得分:0)

&#13;
&#13;
function LetterCountI(str) { 

var word_arr = str.split(" ");
  var x = word_arr.slice();
  
  for(var i = 0; i < x.length; i ++){
    var sum = 0;
    for(var y = 0; y < x[i].length; y++){
      var amount = x[i].split("").filter(function(a){return a == x[i][y]}).length;
      if (amount > 1){
        sum += amount
      }
      
    }
    x[i] = sum;
  }
   var max = Math.max.apply(Math,x);
  if(max == 0)
    return -1;
  var index = x.indexOf(max);
  return(word_arr[index]);
};
&#13;
&#13;
&#13;

这是另一个版本。