Написал генератор тегов не могу найти ошибку
В общем для своего сайта нужно написать генератор тегов на чистом яваскрипте или с использованием ajax.. но я выбрал js. Написал, и вроде даже работало, до тех пор пока не прикрутил слова-исключения, с тех пор код не работает, хотя ошибку не выдает. В js я недавно. И мог упустить что то важное, тем более большая часть кода спионерена(уже не помню где)
Собственно форма такая <textarea id="editor" class="text-area" name="mainText">some text</textarea><!-- так же может подключатся редактор и для записи текста будет использоваться форма с классом .wysibb-text-editor(без дублирования в #editor)--> <input id="keywords" type="text" name="tags" value="сюда генератор выводит теги через запятую" /> <input type="button" value="Get keywords!" onclick="countKeywords()"> <input type="text" value="4" id="minLengthKeyword"> <input type="text" value="3" id="minRepeatKeyword"> <input type="text" value="0.8" id="coincidence"> <input type="text" value="тут слова исключения, если они есть" id="noRepeatKeyword"> И сама логика var keywords1, keywords2 = new Array(), keywords3 = new Array(); function getWords(s) { return s.replace(/[^а-яА-Яa-zA-Z]+/g, " ").toLowerCase(); // Возвращаем массив только из букв } function getKeywords(s) { var tmp; tmp = getWords(s); return tmp.split(" "); // Возвращаем массив тегов } function countKeywords () { var s = $('#editor').attr("value") + $('.wysibb-text-editor').html(); // Получаем текст из которого нужно выделить теги var noRepeatKeyword = $('#noRepeatKeyword').attr("value"), // Получаем слова-исключания re = /\s*,\s*/, // убираем пробелы вокруг запятых NoTags = noRepeatKeyword.split(re);// Выделяем массив слов-исключений var minLengthKeyword = parseInt(document.getElementById('minLengthKeyword').value), // Минимальная длинна тега minRepeatKeyword = parseInt(document.getElementById('minRepeatKeyword').value), // Минимальное количество его повторений coincidence = parseFloat(document.getElementById('coincidence').value); // Коэффицент совпадения var tmpKeywords1 = getKeywords(s), tmpKeywords2 = new Array(); for (i=0;i<tmpKeywords1.length;i++) { // Перебираем полученный массив и создаем новый из удовледворяющих условию элементов var currentWord = tmpKeywords1[i], DeleteWord = false, n=0; while ((n<NoTags.length) && (DeleteWord = true)) { if (currentWord = NoTags[n]) {DeleteWord = true;} // если элемент из тегов совпадает с одним из исключаений назначаем флаг n= n+1; } if ((currentWord.length >= minLengthKeyword) && (DeleteWord = false)) { keywords2.push(currentWord); // Добавляем в массив результатов если length >= minLengthKeyword и если это слово не входит в исключения } } for (i=0;i<keywords2.length;i++) { // Перебираем полученный массив и создаем новый из удовледворяющих условию элементов var currentWord = keywords2[i]; currentWordCore = currentWord.substr(0,Math.round(currentWord.length*coincidence)); var inwords2 = keywords2.grep(currentWordCore); if (inwords2.length >= minRepeatKeyword && keywords3.grep(currentWordCore).length <1) { keywords3.push(currentWord); } } document.getElementById('keywords').value = keywords3; keywords2 = new Array(); keywords3 = new Array(); } // Создаем и выводим строку тегов function grep(str) { var ar = new Array(); var arSub = 0; for (var i in this) { if (typeof this[i] == "string" && this[i].indexOf(str) != -1){ ar[arSub] = this[i]; arSub++; } } return ar; } Array.prototype.remove=function(s){ for(i=0;i<this .length;i++){ if(s==this[i]) this.splice(i, 1); } } Array.prototype.grep = grep; |
Цитата:
|
MrBoriska,
где элементы из 11 строки? и в jquery есть .val() |
Цитата:
|
Цитата:
Ошибка где то ниже, с проверкой на то, что элемент массива равен какому-нибудь элементу из массива слов исключений. Спасибо за .val(), я еще не знаю всех функций. |
в строке 30 - (DeleteWord = true) - всегда возвращает труэ
и в строке 35 - (DeleteWord = false) - всегда фалсэ обычно так не делают :nono: условие в строке 35 никогда не выполнится |
Цитата:
|
Цитата:
|
finestra,
ок |
Спасибо за найденные ошибки) Я еще не очень вник в типы данных, поэтому не знал что проверки нужно делать на тождественности.
Вот исправленный код, который начал выводить теги, как и раньше. Но цикл while, который должен сравнить элемент текущей итерации цикла for со всеми элементами массива NoTags[] и при любом совпадении устанавливать флаг DeleteWord = true что завершает цикл while... походу не работает. var keywords1, keywords2 = new Array(), keywords3 = new Array(); function getWords(s) { return s.replace(/[^а-яА-Яa-zA-Z]+/g, " ").toLowerCase(); // Возвращаем массив только из букв } function getKeywords(s) { var tmp; tmp = getWords(s); return tmp.split(" "); // Возвращаем массив тегов } function countKeywords () { var s = $('#editor').val() + $('.wysibb-text-editor').html(); // Получаем текст из которого нужно выделить теги var noRepeatKeyword = $('#noRepeatKeyword').val(), // Получаем слова-исключания re = /\s*,\s*/, // убираем пробелы вокруг запятых NoTags = noRepeatKeyword.split(re);// Выделяем массив слов-исключений var minLengthKeyword = parseInt($('#minLengthKeyword').val()), // Минимальная длинна тега minRepeatKeyword = parseInt($('#minRepeatKeyword').val()), // Минимальное количество его повторений coincidence = parseFloat($('#coincidence').val()); // Коэффицент совпадения var tmpKeywords1 = getKeywords(s), tmpKeywords2 = new Array(); for (i=0;i<tmpKeywords1.length;i++) { // Перебираем полученный массив и создаем новый из удовледворяющих условию элементов var currentWord = tmpKeywords1[i], DeleteWord = false, n=0; while ((n<NoTags.length) && (DeleteWord === true)) { if (currentWord = NoTags[n]) { DeleteWord = true; } // если элемент из тегов совпадает с одним из исключаений назначаем флаг n=n+1; } if ((currentWord.length >= minLengthKeyword) && (DeleteWord === false)) { keywords2.push(currentWord); // Добавляем в массив результатов если length >= minLengthKeyword и если это слово не входит в исключения } } for (i=0;i<keywords2.length;i++) { // Перебираем полученный массив и создаем новый из удовледворяющих условию элементов var currentWord = keywords2[i]; currentWordCore = currentWord.substr(0,Math.round(currentWord.length*coincidence)); var inwords2 = keywords2.grep(currentWordCore); if (inwords2.length >= minRepeatKeyword && keywords3.grep(currentWordCore).length <1) { keywords3.push(currentWord); } } document.getElementById('keywords').value = keywords3; keywords2 = new Array(); keywords3 = new Array(); } // Создаем и выводим строку тегов function grep(str) { var ar = new Array(); var arSub = 0; for (var i in this) { if (typeof this[i] == "string" && this[i].indexOf(str) != -1){ ar[arSub] = this[i]; arSub++; } } return ar; } Array.prototype.remove=function(s){ for(i=0;i<this .length;i++){ if(s==this[i]) this.splice(i, 1); } } Array.prototype.grep = grep; |
MrBoriska,
может для примера что на входе что на выходе должно быть? |
обычная строка(берете любой пост хоть от сюда и подставляете). Как сейчас мы пишем посты вот такого типа и у меня. Код просто должен генерировать слова которые повторяются в тексте, а число повторений и коэффициент указывает юзер,
а так же он указывает через запятую слова, которые генератор не должен учитывать, но у меня, именно вот этот пункт почему то не работает. Может там где функция grep(), что то не то, а то я не понимаю вообще зачем она, точнее понимаю зачем, но не понимаю как она так это делает(там подписано что). |
MrBoriska,
ваш код разбирать видимо охотников мало, легче написать новый еслибы вы чётко описали свой генератор ... что на входе что на выходе я попрежнему незнаю несмотря на ваши обьяснения |
На выходе должна быть строка, состоящая из слов перечисленных через запятую.
На входе должно быть три переменные: 1. Строка, состоящая из набора слов, символов, пробелов и даже html тегов. 2. Число, которое означает минимальное количество символов в слове. 3. Число, означающее минимальное количество повторений слова в тексте. 4. Слова, перечисленные через запятую, которые не следует учитывать при выводе результата. Программа должна работать примерно по такому алгоритму. 1. Из переменной 1 выкидываются спец. символы и html теги, остается только сам текст и пробелы между словами. Из полученного текста формируется массив, элементы которого - это слова, отделенные друг от друга пробелом в тексте. 2. В массиве ищутся совпадающие элементы и из этих элементов, количество совпадений которых больше или равно переменной 3 формируется новый массив.(заметье с учетом введенного в переменной 4 коэффициента совпадения) 3. Из полученного массива выкидываются элементы, количество букв которых меньше чем указано в переменной 2, а так же элементы которые указаны в переменной 4 через запятую. 4. Из полученного массива формируем строку, в которой элементы этого массива будут перечислены через запятую. Так понятно? Да и вроде код мой тоже относительно понятный, кроме двух последних функций. |
мне конечно тоже лень, разбираться что как работает,
но вот в строке 27, вы присваиваете DeleteWord = false, в while (строка 30), в условии написано, что оно может выполниться если DeleteWord === true, но обрести значение труэ DeleteWord может только внутри цикла, выходит, что цикл никогда не запустится. |
функция countKeywords () большая,
раздели ее на несколько функций поменьше, и каждую протестируй. |
MrBoriska,
function gen(str, len, repeat,tabu) { var obj_tabu = {}; for (var i=0; i<tabu.length; i++) {obj_tabu[tabu[i]]=!0};//сформировали обьект из запретных слов str = str.replace(/<[^>]*>/g, ' ');//выкусили теги str = str.replace(/[^a-zа-яё\s]/gi, ' '); //убрали небуквы str = str.split(/\s+/) ;//сформировали массив слов из строки var obj_output = {}; for (var i=0; i<str.length; i++) { var word = str[i]; if(word.length >= len && !obj_tabu[word]) obj_output[word]=(obj_output[word]||0)+1; } // сформировали обьект из разрешённых слов и нужной длины var output = []; for(var word in obj_output) if (obj_output[word] >= repeat) output.push(word);//отобрали слова с нужным повторением return output } var str = 'На выходе должна быть строка, состоящая из слов перечисленных через запятую..'+ 'На входе должно быть три переменные: '+ '1. Строка, состоящая из набора слов, символов, пробелов и даже html тегов. '+ '2. Число, которое означает минимальное количество символов в слове. '+ '3. Число, означающее минимальное количество повторений слова в тексте. '+ '4. Слова, перечисленные через запятую, которые не следует учитывать при выводе результата.' alert(gen(str, 3, 2,['Число','слов']) ) |
finestra,
я уже все протестировал и сразу сказал где код стопорится! Меня это тоже смутило, но даже если изменить на false результат тот же. |
рони,
Огромное спасибо! Буду тестировать и отпишусь о результатах. |
Код работает великолепно, но нету коэффициента совпадения.
Тоесть это еще один параметр, который определяет когда словам совпадать, а когда нет. Определяется он числом с плавающей точкой, От 0 и до 1, где 0 это когда все слова всегда будут совпадать, а когда 1 то только при точном совпадении. Ну допустим при 1 будут равны keyword и keyword, а при 0.8 будут равны keyword и keywords. сделать можно через match(),(так было сделано в старом коде) |
как насчет этого
var coefficient = function(word1, word2) { word1 = word1.toLowerCase(); word2 = word2.toLowerCase(); var r = new RegExp(word1); if(r.test(word2)) { return Math.round((word1.length / word2.length)*10)/10; } else { return 0; } }; var coeff1 = coefficient("keyword", "keywords"), // 0.9 coeff2 = coefficient("keyFord", "keywords"); // 0 coeff2 должен быть 0? |
Желательно доработать тот код, т.к. я уже из того плагин сделал и куча всего на него завязал.
Тоесть код вот такой теперь. function gen(str,tabu,len,repeat,tags,tabuhide) { var str, // Получаем текст из которого нужно выделить теги tabu = tabuhide + tabu.val(), // Получаем слова-исключения len = parseInt(len.val()), // Минимальная длинна тега repeat = parseInt(repeat.val()), // Минимальное количество его повторений tags, output = ''; var tabu = tabu.split(/\s*,\s*/), obj_tabu = {}; for (var i=0; i<tabu.length; i++) {obj_tabu[tabu[i]]=!0}; //сформировали обьект из запретных слов str = str.replace(/<[^>]*>/g, ' '); //выкусили теги str = str.replace(/[^a-zа-яё\s]/gi, ' '); //убрали небуквы str = str.split(/\s+/); //сформировали массив слов из строки var obj_output = {}; for (var i=0; i<str.length; i++) { var word = str[i]; if(word.length >= len && !obj_tabu[word]) obj_output[word]=(obj_output[word]||0)+1; // сформировали обьект из разрешённых слов и нужной длины } var output1 = []; for(var word in obj_output) if (obj_output[word] >= repeat) output1.push(word); //отобрали слова с нужным повторением for (var i=0; i<output1.length; i++) if (i<1) output += output1[i]; else output += ', ' + output1[i]; // создали строку из элементов массива через запятую return tags.val(output); } В общем нужно добавить в функцию еще один аргумент, не трогая положения старых, с коэффициентом совпадения и завязать сам процесс поиска совпадений еще и на нем. Более ничего не надо. Я бы и сам сделал, но в обьектах не шарю вообще. |
правда строку из массива лучше создать join'ом) но это не суть. :)
|
MrBoriska,
пока из вашего описания коффициента совпадения я понял что слова так, атака, тактика и стакан это 1 слово и оно повторилось 4 раза ... предлагаю решать подобные задачи методом job |
Ладно, в любом случае, я свою задачу уже решил, а коэффициент вещь не очень то и нужная.
С наступающим! И всем спасибо! |
Часовой пояс GMT +3, время: 00:02. |