Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javascript上键/值数组的字频_Javascript_Arrays_Word Frequency - Fatal编程技术网

javascript上键/值数组的字频

javascript上键/值数组的字频,javascript,arrays,word-frequency,Javascript,Arrays,Word Frequency,我试图在javascript上实现一段代码,以分析给定字符串上的单词/频率。我的目标是返回一个数组,如下所示: [{text: firstword, size:3 },{text:secondword , size:5 },{text: nword, size: 1},...] 我实现了以下代码,但内存不足,所以我不知道它是否正常 function wordFrequency(txt){ var wordArray = txt.split(/[ .?!,*'"]/); var

我试图在javascript上实现一段代码,以分析给定字符串上的单词/频率。我的目标是返回一个数组,如下所示:

[{text: firstword, size:3 },{text:secondword , size:5 },{text: nword, size: 1},...]
我实现了以下代码,但内存不足,所以我不知道它是否正常

function wordFrequency(txt){
    var wordArray = txt.split(/[ .?!,*'"]/);
    var newArray = [];
    $.each(wordArray, function (ix, word) {
        if (newArray.length >= 1){
            newArray.some(function (w){
                if (w.text === word){
                    w.size++;
                } else {
                    newArray.push({text: word, size: 1});
                }
            });
        } else {
            newArray.push({text: word, size: 1});
        }
    });
    return newArray;
}
期望给定的回调返回true或false,并在回调为给定元素返回true时立即返回true,否则返回false

因此,
some
使用给定的回调对所有元素进行迭代,回调检查给定的元素文本是否等于搜索词,如果不是,则添加一个新对象。引入一个新元素,
某些
函数可以迭代

为了说明这一点,对于
newArray
中搜索单词之前的每个单词,您添加了一个包含单词的新对象

假设您的
newArray
如下所示:

[{word:“test”},{word:“other”},{word:“one”},{word:“more”}]

为单词
偶数
调用函数后,如下所示:

[{word:“test”},{word:“other”},{word:“one”},{word:“more”},{word:“偶”},{word:“偶”},{word:“偶”}]

在这里使用将是更好的方法,找到匹配的元素,请注意,我还将
$替换为每个

函数字频率(txt){
var wordArray=txt.split(/[.?!,*'“]/);
var newArray=[],wordObj;
forEach(函数(word){
wordObj=newArray.filter(函数(w){
返回w.text==word;
});
if(文字对象长度){
wordObj[0]。大小+=1;
}否则{
push({text:word,size:1});
}
});
返回新数组;
}

document.write(JSON.stringify(wordFrequency(“计算所有内容,计算所有单词,计算所有单词!”)).sort(函数(a,b){return a.size告诉频率,你只需要一个哈希映射方法。你的算法是二次的,因为
some
方法嵌套在
每个
方法中,所以你总是在
newArray
上循环,只是为了找到一个条目并增加大小

使用JavaScript对象很容易实现映射方法,它还提供了恒定的查找时间,这比嵌套循环方法的性能更好

请尝试以下方法:

function wordFrequency(txt){
    var wordArray = txt.split(/[ .?!,*'"]/);
    var map = {};
    $.each(wordArray, function(ix, word) {
      // skip empty results
      if (!word.length) {
        return;
      }
      // add word to map
      if (!map[word]) {
        map[word] = 0;
      } 
      map[word]++;
    });
    return map;
}
要使用该功能,请执行以下操作:

var text = "hello!world*hello foo  'bar'foo";
var result = wordFrequency(text);

// iterate over results
Object.keys(result).forEach(function(w) {
  console.log(w + ": " + result[w]);
});

// or use for...in
for (var w in result) {
  console.log(w + ": " + result[w]);
}
如果确实需要,可以使用文本和大小属性将结果映射到所需的数组格式:

var mappedResult = Object.keys(result).map(function(w) {
  return { text: w, size: result[w] };
});
console.log(mappedResult);

此外,根据您的目标浏览器,您可以考虑使用数组<代码> PROACH <代码>,而不是jQuery <代码> $>每个,类似于我使用的<>代码>对象。


以下是。

您可能希望避免对重复元素进行任何迭代,并保持结果数组的唯一性。由于array.prototype的任何迭代器都将包含每个元素,因此它们可能不是解决此问题的理想解决方案。有时简单的旧循环最适合。。。 (您可能还希望以表达式方式转义正则表达式中的任何特殊字符)

将优化考虑在内,使用显式循环的第一个版本可能会执行得更快…

创建从单词到频率的直接映射,然后再将其转换为数组结构将更简单、更高效。给定数组
单词
创建单词映射:

var freq = words.reduce(function(p, c) {
    p[c] = (p[c] || 0) + 1;
    return p;
}, {});
然后将该贴图转换为数组:

var array = Object.keys(freq).map(function(key) {
   return { text: key, size: freq[key] };
});
var words=(函数(){
var swarks=document.body.innerText.toLowerCase().trim().replace(/[,;.]/g',).split(/[\s\/]+/g).sort();
var iwordscont=swarks.length;//计数w/重复项
//要忽略的单词数组
var ignore=['and'、'the'、'to'、'a'、'of'、'for'、'as'、'i'、'with'、'it'、'is'、'on'、'that'、'this'、'can'、'in'、'be'、'has'、'if'];
忽略=(函数(){
var o={};//数组检查中的对象属性检查>
var iCount=ignore.length;

对于(var i=0;iIt在我的控制台中是可以的,但会有重复的结果,我尝试了这个:wordFrequency(“negin!kjs$wkjh*df oiuw&skdjhh”);我尝试使用大量文本,每次都会出现内存不足的情况,即使尝试使用jsfiddle时也是如此(因为当你有空间的时候,你不应该把它算作一个词,只要把空间移走,再试一次,我的意思是:txt.split(/[.?!,“]/);移走,取而代之的是:txt.split(/[.?!,“]/);那些
看到的到底是什么。按一下
频率线
应该做什么?!后者应该是
freq[w]=1
,以后您可以使用
Object.keys(freq)
来获取唯一单词的列表。@Alnitak这是假设顺序具有任何重要性。因为我们不知道任何用例,所以我们无权放弃此信息(使用关联数组/哈希时也是如此)。我猜这会很有意义,因为使用对象键的问题很小。(如果(看到[w])freq[w]++;)好的,我理解你现在想做什么,尽管结果仍然是一个
O(n*m)
算法。你不会真正解决这个问题,因为即使是散列查找(freq[w])它相当于一个内部循环。它可能会更有性能,因为散列可能是内部排序的,但也有一个产生哈希密钥的惩罚。对于一个真正的大文本,我们可以考虑使用B-树来存储所看到的任何单词,但我怀疑这将是一个用例。问题不是O(n*m/2),而是可能。$.each“。循环版本在任何时候都会执行,而此页面的文本内容不会出现问题。最好使用wordArray.forEach(函数(word){});
var freq = words.reduce(function(p, c) {
    p[c] = (p[c] || 0) + 1;
    return p;
}, {});
var array = Object.keys(freq).map(function(key) {
   return { text: key, size: freq[key] };
});
var words = (function(){

var sWords = document.body.innerText.toLowerCase().trim().replace(/[,;.]/g,'').split(/[\s\/]+/g).sort();
var iWordsCount = sWords.length; // count w/ duplicates

// array of words to ignore
var ignore = ['and','the','to','a','of','for','as','i','with','it','is','on','that','this','can','in','be','has','if'];
ignore = (function(){
var o = {}; // object prop checking > in array checking
var iCount = ignore.length;
for (var i=0;i<iCount;i++){
o[ignore[i]] = true;
}
return o;
}());

var counts = {}; // object for math
for (var i=0; i<iWordsCount; i++) {
var sWord = sWords[i];
if (!ignore[sWord]) {
counts[sWord] = counts[sWord] || 0;
counts[sWord]++;
}
}

var arr = []; // an array of objects to return
for (sWord in counts) {
arr.push({
text: sWord,
frequency: counts[sWord]
});
}

// sort array by descending frequency | http://stackoverflow.com/a/8837505
return arr.sort(function(a,b){
return (a.frequency > b.frequency) ? -1 : ((a.frequency < b.frequency) ? 1 : 0);
});

}());

(function(){
var iWordsCount = words.length; // count w/o duplicates
for (var i=0; i<iWordsCount; i++) {
var word = words[i];
console.log(word.frequency, word.text);
}
}());