2016-11-26 44 views
0

我试图从字符串中删除停用词的列表。该列表使用$ .get在下面的第3行加载。 如果我尝试在$ .get函数内部使用console.log(stop_words),我可以检索数据。但是它们不会以某种方式添加到数组stop_words中,以便我可以使用$ .get函数之外的数据。JavaScript加载txt单词列表将不会填充数组

注:下面的代码工作正常,如果我直接在原型中声明数组的值。

如何以这种方式将数据分配给stop_words数组,以便在$ .get函数之外使用它?

String.prototype.removeStopWords = function() { 
    var stop_words = []; 
    $.get('rsc/stopord.txt', function(data) { 
     stop_words = data.split('\n'); 
    }); 
    var x; 
    var y; 
    var word; 
    var stop_word; 
    var regex_str; 
    var regex; 

    var cleansed_string = this.valueOf(); 

    // Split out all the individual words in the phrase 
    words = cleansed_string.match(/[^\s]+|\s+[^\s+]$/g) 

    // Review all the words 
    for(x=0; x < words.length; x++) { 
     // For each word, check all the stop words 
     for(y=0; y < stop_words.length; y++) { 
      // Get the current word 
      word = words[x].replace(/\s+|[^a-z]+/ig, ""); // Trim the word and remove non-alpha 

      // Get the stop word 
      stop_word = stop_words[y]; 

      // If the word matches the stop word, remove it from the keywords 
      if(word.toLowerCase() == stop_word) { 
       // Build the regex 
       regex_str = "^\\s*"+stop_word+"\\s*$";  // Only word 
       regex_str += "|^\\s*"+stop_word+"\\s+";  // First word 
       regex_str += "|\\s+"+stop_word+"\\s*$";  // Last word 
       regex_str += "|\\s+"+stop_word+"\\s+";  // Word somewhere in the middle 
       regex = new RegExp(regex_str, "ig"); 

       // Remove the word from the keywords 
       cleansed_string = cleansed_string.replace(regex, " "); 
      } 
     } 
    } 
    return cleansed_string.replace(/^\s+|\s+$/g, ""); 
} 

function keywordDensity() { 
    var input = tinyMCE.activeEditor.getContent({format : "text"}); 
    input = input.replace(/(<([^>]+)>)/ig, "").replace(/,/g, "").replace(/-/g, "").replace(/"/g, "").replace(/'/g, "").replace(/\./g, " "); 
    input = input.toLowerCase(); 
    input = input.removeStopWords(); 
    console.log(input); 
    var keyword = $("#keyword").html(); 
    var wordCounts = { }; 
    var words = input.split(" "); 
    words = words.filter(Boolean); 

    for(var i = 0; i < words.length; i++) 
     wordCounts["_" + words[i]] = (wordCounts["_" + words[i]] || 0) + 1; 

    keysSorted = Object.keys(wordCounts).sort(function(a,b){return wordCounts[b]-wordCounts[a]}) 

    for(var i = 0; i < keysSorted.length; i++) { 
     keysSorted[i] = keysSorted[i].replace(/[_-]/g, ""); 
    } 

    var regexString = keysSorted[0]; 
    var regex = new RegExp("\\b" + regexString, 'g'); 
    var countMostUsed = input.match(regex, regexString); 
    console.log(input.match(regex, regexString)); 
    console.log("You use the word " + keysSorted[0] + " " + countMostUsed.length + " times"); 
    } 
+3

您的$ get需要onsuccess事件。异步加载。 – Mistergreen

+1

'$ .get()'是**异步**。当HTTP请求完成时,您传入的回调将被调用,但对$ .get()的调用本身立即返回。基本上,你的代码中的大部分工作都应该在回调中完成。 – Pointy

+0

@Mistergreen是正确的,只是为了更清楚一点:代码中的所有内容都能正常工作,问题在于,您的函数并没有等待您的$ .get调用在运行其余代码之前完成,因此您的代码会保留运行并且您的stop_word尚未填充。因此,将您的代码添加到成功回调函数中。 – phobia82

回答

1

As @Mistergreen, @Pointy和@phobia82已经评论过,你需要在回调中进行处理。或者更好的是,在收到数据后,使用then

String.prototype.removeStopWords = function() { 

    var stop_words = []; 
    var self = this; 
    return $.get('stopword.txt', function(data) { 
     stop_words = data.split('\r\n'); 
    }).then(function(){ 
     var x; 
     var y; 
     var word; 
     var stop_word; 
     var regex_str; 
     var regex; 

     var cleansed_string = self.valueOf(); // note: we can't use this here 

     // Split out all the individual words in the phrase 
     words = cleansed_string.match(/[^\s]+|\s+[^\s+]$/g) 

     // Review all the words 
     //for(x=0; x < words.length; x++) { 
      // For each word, check all the stop words 
      for(y=0; y < stop_words.length; y++) { 
       // Get the current word 
       //word = words[x].replace(/\s+|[^a-z]+/ig, ""); // Trim the word and remove non-alpha 

       // Get the stop word 
       stop_word = stop_words[y]; 

       // If the word matches the stop word, remove it from the keywords 
       //if(word.toLowerCase() == stop_word) { 
        // Build the regex 
        regex_str = "^\\s*"+stop_word+"\\s*$";  // Only word 
        regex_str += "|^\\s*"+stop_word+"\\s+";  // First word 
        regex_str += "|\\s+"+stop_word+"\\s*$";  // Last word 
        regex_str += "|\\s+"+stop_word+"\\s+";  // Word somewhere in the middle 
        regex = new RegExp(regex_str, "ig"); 

        // Remove the word from the keywords 
        cleansed_string = cleansed_string.replace(regex, " "); 
       // } 
      } 
     //} 
     return cleansed_string.replace(/^\s+|\s+$/g, ""); 

    }); 
} 

注:我不知道为什么你需要在String个人words迭代。所以我已经评论了这一部分。你可以找到工作代码here

你需要改变你调用函数的方式,如下所示。

"abc test1 test2 xyz".removeStopWords().then(function(data){ 
    alert(data); // alerts "abc xyz" 
    // do rest of the processing that is dependent on the return value of `removeStopWords` 
}); 
+0

感谢一堆。我从来没有做过任何事情,所以我花了一段时间才能完成这项工作。但现在它是完美的:D –

0

这是不推荐,因为您的GET请求可以阻止你的脚本,直到它返回一个结果,但根据记录,你可以用它来代替$获得():

$.ajax({ 
    url: 'rsc/stopord.txt', 
    success: function(data) { 
     stop_words = data.split('\n'); 
    }, 
    async: false 
}) 

编辑:

您的成功回调函数:

function(data) { 
    stop_words = data.split('\n'); 
} 

你传递给$ .get()调用。它在$ .get请求收到响应时调用,这可能需要一些时间... $ .get之后的代码可以在调用回调之前运行,因此您的问题...