2016-06-30 3 views
4

こんにちは、javascriptで単語型モデルのシンプルな袋を開発する方法を探していましたが、私が見たものからjnodeまたはbrowserifyをインストールする必要があります。 テキストを読み込み、分割してテキスト中で最も頻繁に使用される単語を取得しようとしていますが、JavaScript値を返すためにjavascriptの配列オブジェクトを使用して問題が発生しましたが、これまでは番号付きインデックスのみを返します。配列の中の出現回数をカウントしてトップ値を得る簡単な方法

function bagOfWords(text){ 
text=text.toLowerCase(); //make everything lower case 
var bag = text.split(" "); //remove blanks 

//count duplicates 
var map = bag.reduce(function(prev, cur) { 
    prev[cur] = (prev[cur] || 0) + 1; 
    return prev; 
}, {}); 


var arr = Object.keys(map).map(function (key) { return map[key]; }); //index based on values to find top 10 possible tags 
arr=arr.sort(sortNumber); //sort the numbered array 

var top10 = new Array(); //the final array storing the top 10 elements 
for (i = arr.length; top10.length < 10; i--) { 
if(top10.length<10){ 
top10.push(arr[i]);} 

} 

} 

reduceメソッドを使用してインデックスを繰り返し、元のテキスト入力を参照しなくても(新しいソートされた配列を作成せずに)、reduceメソッドを使用して上位10語を検索、数え、検索する簡単な方法はありますか?

+1

マップを使用しないでください(必ずしも[ES6 Map](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map)) 'var map = {} '現在の単語をマップキーとして使用する' var count = map [word]; if(count ===未定義)count = 1;そうでなければcount + = 1; map [word] = count; 'しかし、この方法では、地図内のすべてを繰り返して、最も高い数値を見つける必要があります。 –

+0

ああ、良いアイデア、すべての助けてくれてありがとう! – D3181

答えて

2

問題への良いreduce解決策があるかどうかはわからないが、私は、アルゴリズムを作ってみた:

  1. ソートすべての単語、およびこの配列のクローンを作成。
  2. クローン化配列にlastIndexOf()indexOf()を使用して発生逆の順序で並べ替え単語のソートされたリストを、。
  3. filter()重複を削除する新しい配列。
  4. slice()フィルタリングされた配列を最初の10語に制限します。

スニペット:

function bagOfWords(text) { 
 
    var bag = text. 
 
       toLowerCase(). 
 
       split(' '). 
 
       sort(), 
 
     clone = bag.slice(); //needed because sort changes the array in place 
 
      
 
    return bag. 
 
      sort(function(a, b) { //sort in reverse order of occurrence 
 
    \t  return (clone.lastIndexOf(b) - clone.indexOf(b) + 1) - 
 
     \t    (clone.lastIndexOf(a) - clone.indexOf(a) + 1); 
 
    \t }). 
 
      filter(function(word, idx) { //remove duplicates 
 
      return bag.indexOf(word) === idx; 
 
      }). 
 
      slice(0, 10); //first 10 elements 
 
} //bagOfWords 
 

 
console.log(bagOfWords('four eleven two eleven ten nine one six seven eleven nine ten seven four seven six eleven nine five ten seven six eleven nine seven three five ten eleven six nine two five seven ten eleven nine six three eight eight eleven nine ten eight three eight five eleven eight ten nine four four eight eleven ten five eight six seven eight nine ten ten eleven ')); 
 

 
console.log(bagOfWords('Four score and seven years ago our fathers brought forth on this continent a new nation conceived in Liberty and dedicated to the proposition that all men are created equal Now we are engaged in a great civil war testing whether that nation or any nation so conceived and so dedicated can long endure We are met on a great battle-field of that war We have come to dedicate a portion of that field as a final resting place for those who here gave their lives that that nation might live It is altogether fitting and proper that we should do this But in a larger sense we can not dedicate we can not consecrate we can not hallow this ground The brave men living and dead who struggled here have consecrated it far above our poor power to add or detract The world will little note nor long remember what we say here but it can never forget what they did here It is for us the living rather to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced It is rather for us to be here dedicated to the great task remaining before us that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion that we here highly resolve that these dead shall not have died in vain that this nation under God shall have a new birth of freedom and that government of the people by the people for the people shall not perish from the earth'));

1

Array.prototype.reduce()を使用する必要がありますか?このメソッドは、要素の配列全体を1つの値に減らし、ユースケースに合うようには聞こえません。単純に言葉の出現を数えたいのなら、私は辞書を使いたいです。

function bagOfWords(text, topCnt) { 
 
    text= text.toLowerCase(); //make everything lower case 
 
    var bag = text.split(" "); //remove blanks 
 
    //Remove "." and possibly other punctuation? 
 

 
    //build the word dictionary; 
 
    var wordDict = {}; 
 
    for(idx in bag) { 
 
    if(bag[idx] in wordDict) { 
 
     wordDict[bag[idx]]++; 
 
    } 
 
    else { 
 
     wordDict[bag[idx]] = 1; 
 
    } 
 
    } 
 
    //get the duplicate free array 
 
    var dupFree = []; 
 
    for(word in wordDict) { 
 
    dupFree.push(word); 
 
    } 
 
    //find the top topCnt; 
 
    //Custom sort method to sort the array based on the dict we created. 
 
    var sorted = dupFree.sort(function(a, b) { 
 
    if (wordDict[a] > wordDict[b]) { 
 
     return -1; 
 
    } 
 
    if (wordDict[a] < wordDict[b]) { 
 
     return 1; 
 
    } 
 
    return 0; 
 
    }); 
 
    
 
    //Now we can just return back the spliced array. 
 
    //NOTE - if there is a tie, it would not return all the ties. 
 
    // For instance, if there were twenty words with each having the same occurance, this would not return back all 20 of them. To do that, you would need another loop. 
 
    return sorted.slice(0,topCnt); 
 
} 
 

 
    var lorem = "Lorem ipsum dolor sit amet consectetur adipiscing elit Duis gravida, lectus vel semper porttitor nulla nulla semper tortor et maximus quam orci a nibh Duis vel aliquet est Aliquam at elit libero Duis molestie nisi et lectus fringilla vulputate Integer in faucibus dolor Vivamus leo magna, interdum sit amet arcu et vulputate aliquam elit Pellentesque vel imperdiet nisi maximus malesuada eros Aenean sit amet turpis lorem Pellentesque in scelerisque ante Nunc sed dignissim ex Quisque neque risus feugiat a felis vitae blandit tristique mauris Etiam pharetra eleifend felis ac cursus Pellentesque ac magna nec lectus interdum lacinia Fusce imperdiet libero accumsan dolor consectetur, sed finibus justo ornare. Vivamus vehicula ornare metus quis fermentum sapien ullamcorper non Cras non odio interdum facilisis elit sit amet facilisis risus"; 
 
console.log(bagOfWords(lorem,10));

は間違いなく私がコメントで述べたように、行うことができるいくつかの改善があります。これは少なくともあなたを始めさせるはずです。ここでの魔法は、辞書を使用して重複を削除し、出現回数を数え、次にカスタムソート関数を使用して、必要な順序で配列を整列させることです。

すべてのjavascript機能のニーズについては、MDNをご覧ください。このサイトは素晴らしいリソースです。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

+0

助けてくれてありがとう、あなたのサンプルとリンクは、この問題、特にあなたのコメントを解決する助けに非常に役立ちました。他のどれもあなたのプロセスに従って理解するのを本当に助けたコメントであなたのものと大きく分けられませんでした。 – D3181

2

あなたは配列が最も出現を持つ以内に最初の10の項目を返すために、結果から重複したオブジェクトを除外するためのパラメータ0, 10Array.protototype.slice()String.prototype.match()Array.prototype.some()を使用することができます同じ言葉

var text = document.querySelector("div").textContent; 
 

 
var res = text.match(/[a-z]+/ig).reduce((arr, word) => { 
 
    return !arr.some(w => w.word === word) 
 
      ? [...arr, { 
 
       word: word, 
 
       len: text.match(new RegExp("\\b(" + word + ")\\b", "g")).length 
 
      }] 
 
      : arr 
 
}, []) 
 
.sort((a, b) => { 
 
    return b.len - a.len 
 
}); 
 

 
console.log(res.slice(0, 10));
<div> 
 
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam et ipsum eget purus maximus suscipit. Aliquam fringilla eros at lorem venenatis, et hendrerit neque ultrices. Suspendisse blandit, nulla eu hendrerit mattis, elit nibh blandit nibh, non scelerisque leo tellus placerat est. Phasellus dignissim velit metus. Sed quis urna et nunc hendrerit tempus quis eu neque. Vestibulum placerat massa eget sapien viverra fermentum. Aenean ac feugiat nibh, eu dignissim ligula. In hac habitasse platea dictumst. Nunc ipsum dolor, consectetur at justo eget, venenatis vulputate dui. Nulla facilisi. Suspendisse consequat pellentesque tincidunt. Nam aliquam mi a risus suscipit rutrum. 
 

 
Donec porta enim at lectus scelerisque, non tristique ex interdum. Nam vehicula consequat feugiat. In dictum metus a porttitor efficitur. Praesent varius elit porta consectetur ornare. Mauris euismod ullamcorper arcu. Vivamus ante enim, mollis eget auctor quis, tristique blandit velit. Aliquam ut erat eu erat vehicula sodales. Vestibulum et lectus at neque sodales congue ut id nibh. Etiam congue ornare felis eget dictum. Donec quis nisl non arcu tincidunt iaculis. 
 

 
Donec rutrum quam sit amet interdum mattis. Morbi eget fermentum dui. Morbi pulvinar nunc sed viverra sollicitudin. Praesent facilisis, quam ut malesuada lobortis, elit urna luctus nulla, sed condimentum dolor arcu id metus. Donec sit amet tempus massa. Nulla facilisi. Suspendisse egestas sollicitudin tempus. Fusce rutrum vel diam quis accumsan. 
 

 
Etiam purus arcu, suscipit et fermentum vel, commodo a leo. Vestibulum varius purus felis, fringilla blandit lacus luctus varius. In tempus imperdiet risus ut imperdiet. Ut ut faucibus nunc. Vivamus augue orci, lobortis at enim non, faucibus pharetra est. Pellentesque ante arcu, rhoncus eu lectus nec, ornare molestie lorem. Suspendisse at cursus erat. Vivamus quis lacinia neque. Donec euismod neque eget purus faucibus hendrerit. 
 

 
Fusce in ante placerat, aliquam mauris et, condimentum ligula. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris hendrerit egestas risus, at consequat metus interdum et. Proin ut tellus quis lorem auctor tempor. Mauris viverra ligula et finibus iaculis. Mauris quis enim a lorem bibendum cursus nec nec enim. Etiam porttitor ligula et erat sagittis vulputate. Fusce ornare mi quis ante faucibus mattis. Aliquam tristique libero sed magna dapibus, vitae sollicitudin lorem malesuada. Praesent dignissim malesuada tellus vitae facilisis. Nullam diam augue, tincidunt ut maximus non, convallis vel felis. 
 
</div>

+0

あなたのサンプルも例外的にうまくいったので、ページのすべての人が実際に私の質問に対するすべての有効な回答だったので、質問に対する最終的な答えを選ぶのに苦労しました。助けてくれてありがとうと私はそれを感謝し、私はこの問題を解決するために使用されたコードのいくつかの行と私は驚いて、 – D3181

1

ここでは別のアルゴリズムを行く:

function myCounter(bagWords) { 

    // Create an array of bag words from string 
    var bagMap = bagWords.toLowerCase().split(' '); 

    // Count duplicates 
    var bagCount = bagMap.reduce((countWords, word) => { 
     countWords[word] = ++countWords[word] || 1; 
     return countWords; 
    }, {}); 

    // Create a sorted array 
    var bagResult = []; 
    return bagResult = Object.keys(bagCount).map(function(el, i) { 
     bagResult.push(bagCount[el]); 
     return { 
      word: el, 
      count: bagCount[el] 
     }; 
    }).sort((a,b) => {  
     return b.count-a.count; 
    }).slice(0,10); 

} 

var bagWords = "Pat cat hat Tat bat rat pat Cat Hat tat Bat Rat test pat pat bat bat tap tac eat bat Ope ope Asd Eat dsa"; 
console.log(myCounter(bagWords)); 

多分それが誰かを助けすることができます。

関連する問題