Split string as per the text AND , NOT? - javascript

I have string like below:
var str ='video AND music NOT movie AND moble NOT laptop';
Above string split after AND and NOT and store in 2 different arrays.
After AND text in different array.
After NOT text different array dynamically.
Output looks like
["video","music","mobile"],["movie","laptop"]

function haveAndNots(str) {
var nots = [];
str = str.replace(/NOT (\w+)/g, function(m, c) {
nots.push(c);
return '';
});
return {
have: str.split('AND').map(str => str.trim()),
nots: nots
}
}
var str = 'video AND music NOT movie AND mobile NOT laptop';
var split = haveAndNots(str);
console.log(split.have);
console.log(split.nots);

Use split function.
var str = 'video AND music NOT movie AND moble NOT laptop';
var strAnd = [];
var strNot = [];
var temp = str.split(' ');
$.each(temp, function(key, value) {
if (value === 'AND') {
strAnd.push(temp[key + 1])
} else if (value === 'NOT') {
strNot.push(temp[key + 1])
}
});
console.log(strAnd,strNot);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Related

Javascript - how to render an output by typing three (or more) alphabets into the input?

I am making an html page which is a typer of a foreign script.
my progress: HERE
Here's the entire javascript:
function getReplacedText(latinText) {
if (!latinText) {
return "";
}
var replacedText = "";
for (var i = 0, len = latinText.length; i < len; i++) {
var curLetter = latinText[i];
var pos1Txt = latinText[i + 1];
var pos2Txt = latinText[i + 2];
if (!(curLetter == "")) {
var dualLetter = latreplaced[curLetter + pos1Txt];
if (dualLetter) {
replacedText += dualLetter;
i++;
continue;
}
}
replacedText += latreplaced[curLetter] || curLetter;
}
return replacedText;
}
var latreplaced = {
"u":"う",
"ku":"く",
"tsu":"つ",
};
function onLatinTextChange(txt) {
var replacedTextareaElem = document.getElementById("replaced_textarea");
var div = document.createElement("div");
var replacedHtmlEntities = getReplacedText(txt);
div.innerHTML = replacedHtmlEntities;
replacedTextareaElem.value = div.innerText;
}
The purpose of this project is to create a virtual phonetic keyboard to type certain forign scripts by only using Latin alphabets, without its keyboard setting installed.
Basically, if you enter an alphabet into the input <textarea>, it renders its corresponding foreign alphabet. (For instance, input 'u' > output 'う', input 'ku' > output 'く')
Here is my problem: So far I have enabled rendering an output when one or two alphabet is typed into the input box. But I cannot figure out how to enable the same by entering three alphabets. (For instance, input 'tsu' > output 'つ')
"u":"う", // <- can convert
"ku":"く", // <- can convert
"tsu":"つ", // <- cannot convert!
In the javascript code, there is a var called dualLetter, which goes by the following script:
var dualLetter = latreplaced[curLetter + pos1Txt];
How can I edit this part of code (or the entire javascript) to be able to convert 3 or more input alphabets? Do I need to make var tripleLetter, or create a whole new system? Any alternative ways would also be helpful.
[edit] a solution inspired by your code :
I changed the main function but this definitively works
live demo : https://jsfiddle.net/alias_gui3/wds426mq/12/
source code :
var dictionnary = {
"u":"う",
"ku":"く",
"tsu":"つ",
"test for spaces": "😍"
};
var maxLength = Object.keys(dictionnary)
.reduce((a, b) => a.length > b.length ? a : b) // get the longest word
.length; // and it's length
function translate (text) {
var translated = "";
var cur = 0;
while (cur < text.length) {
var testedPhoneme;
var symbol = undefined;
for (var length = maxLength; length > 0; length --) {
testedPhoneme = text.substr(cur, length);
if (dictionnary[testedPhoneme]) {
symbol = dictionnary[testedPhoneme];
break; // stop the loop
}
}
if (symbol) {
translated += symbol;
cur += testedPhoneme.length;
}
else {
translated += text[cur]
cur++;
}
}
return translated
}
function onLatinTextChange(txt) {
var replacedTextareaElem = document.getElementById("replaced_textarea");
var div = document.createElement("div");
var replacedHtmlEntities = translate(txt);
div.innerHTML = replacedHtmlEntities;
replacedTextareaElem.value = div.innerText;
}
[previous post] a simple solution :
I suggest you split your text using spaces
If i understand well, you want to type u ku tsu to get うくつ, not ukutsu, if this is right then something like that could work :
const dictionnary = {
"u": "う",
"ku": "く",
"tsu": "つ"
var phonemes = text.split(' ') // split text by spaces
var translatedArray = phonemes.map(function (phoneme) {
return dictionnary[phoneme] || phoneme
// will return the latin phoneme if it is not in the dictionnary
})
translatedString = translatedArray.join('')

Word Order in Search Bars Using JavaScript

Explanation. I am new to VueJS and JavaScript and I am trying to setup a search bar. So far, it works well, but I have one issue with it. I would like to be able to search through a description of an object even if the words I typed in the search bar are not in the correct order.
Example.
The string in the description would be "Gucci blue belt". If I type "Gucci blue", the result shows up since the description contains those words in this exact order. Therefore, I would like to add the functionality for which I can type "Gucci belt" and the item with the description "Gucci blue belt" would show up.
My current code in the computed section in VueJS
filteredsortedobjects (){
return this.sortedobjects.filter(object => {
var Objectslist_n = object.name;
var Objectslist_q = object.quantity;
var Objectslist_c = object.category;
var Objectslist_s = object.section;
var Objectslist_d = object.description;
var Objectslist_date = object.reception_date;
var Input = this.searchQuery;
/* Form arrays with all the information in the table */
var Objectslist_nq = Objectslist_n.concat(Objectslist_q);
var Objectslist_nqc = Objectslist_nq.concat(Objectslist_c);
var Objectslist_nqcs = Objectslist_nqc.concat(Objectslist_s);
var Objectslist_nqcsd = Objectslist_nqcs.concat(Objectslist_d);
var Objectslist_nqcsddate = Objectslist_nqcsd.concat(Objectslist_date);
/* Filtered variables */
var F_Objectslist = RemoveAccents(Objectslist_nqcsddate.toLowerCase());
var F_Input = RemoveAccents(this.searchQuery.toLowerCase());
/* Function to remove accents */
function RemoveAccents(str) {
var accents = 'ÀÁÂÃÄÅàáâãäåÒÓÔÕÕÖØòóôõöøÈÉÊËèéêëðÇçÐÌÍÎÏìíîïÙÚÛÜùúûüÑñŠšŸÿýŽž';
var accentsOut = "AAAAAAaaaaaaOOOOOOOooooooEEEEeeeeeCcDIIIIiiiiUUUUuuuuNnSsYyyZz";
str = str.split('');
var strLen = str.length;
var i, x;
for (i = 0; i < strLen; i++) {
if ((x = accents.indexOf(str[i])) != -1) {
str[i] = accentsOut[x];
}
}
return str.join('');
};
console.log(F_Objectslist);
console.log(F_Input);
return F_Objectslist.includes(F_Input)
})
}
I am aware that the function to remove accents is not yet used since I have been testing things.
What I have tried doing. I have tried setting the variable F_Input (what is being written in the search bar) and F_Objectslist (a variable containing an array with all the words for the items, for instance, the names, the category, the section, the quantity, a description and a date) as strings by array.split(" "). That way, I was able to have an array of strings in this format in the console ["word", "word2", ...] for both my variables.
From this point, I am unsure on how to check if the strings in my F_Input array are all present in the array for F_Objectslist even if they are in a different order.
Thank you so much for your time!
Split F_Input on " ", then you can use 'Array.prototype.map()' to loop through the F_Input array of search terms using the same technique you have now.
Notice that I've chained all these together with a final call to the .every() method. That last one says that every map operation (search) must result in a true (or the result of the map operation must result in an array full of nothing but true);
const F_Objectslist = "this is search term, and this is term search".split(' ');
const F_Input = "search term";
let result = search(F_Objectslist, F_Input);
console.log(result);
let notFoundResult = search(F_Objectslist, "search dog");
console.log(notFoundResult);
function search(text, terms) {
return terms.split(' ').map(term =>text.includes(term)).every(found=>found===true);
}
I think you were already pretty close, I would approach it like this
function searchString(input, match) {
let is_a_match = true;
const match_arr = match.split(' ');
const input_arr = input.split(' ');
input_arr.forEach(word => {
if (match_arr.indexOf(word) === -1) {
is_a_match = false;
}
});
return is_a_match;
}
A working fiddle can be found here
Here is my answer.
I managed to make a quite responsive search bar that seeks information in the array! Here is the code if anyone is curious about it!
page.vue inside computed
filteredsortedobjects (){
return this.sortedobjects.filter(object => {
var Objectslist_n = "a" + object.name;
var Objectslist_c = object.category;
var Objectslist_s = object.section;
var Objectslist_q = object.quantity;
var Objectslist_d = object.description;
var Objectslist_date = object.reception_date;
var Input = this.searchQuery;
/* Form arrays with all the information in the table */
var Objectslist_nc = Objectslist_n + " " + Objectslist_c;
var Objectslist_ncs = Objectslist_nc + " " + Objectslist_s;
var Objectslist_ncsq = Objectslist_ncs + " " + Objectslist_q;
var Objectslist_ncsqd = Objectslist_ncsq + " " + Objectslist_d;
var Objectslist_ncsqddate = Objectslist_ncsqd + " " + Objectslist_date;
/* Filtered variables */
var F_Objectslist = RemoveAccents(Objectslist_ncsqddate.toLowerCase()).split(" ") + " ";
var F_Input = RemoveAccents(this.searchQuery.toLowerCase()).split(" ");
/* Function to remove accents */
function RemoveAccents(str) {
var accents = 'ÀÁÂÃÄÅàáâãäåÒÓÔÕÕÖØòóôõöøÈÉÊËèéêëðÇçÐÌÍÎÏìíîïÙÚÛÜùúûüÑñŠšŸÿýŽž';
var accentsOut = "AAAAAAaaaaaaOOOOOOOooooooEEEEeeeeeCcDIIIIiiiiUUUUuuuuNnSsYyyZz";
str = str.split('');
var strLen = str.length;
var i, x;
for (i = 0; i < strLen; i++) {
if ((x = accents.indexOf(str[i])) != -1) {
str[i] = accentsOut[x];
}
}
return str.join('');
};
return F_Input.every(object => {
if (F_Objectslist.indexOf(object) === -1) {
}
else {
return F_Objectslist.indexOf(object)
}
})
})
}
I have an input with a v-model="searchQuery" attribute. Also, there is a table containing
<tr id="tr" v-for="object in filteredsortedobjects" v-bind:key="object.name">
<td>
<p>{{ object.name }}</p>
</td>
<td>
<p>{{ object.category }}</p>
</td>
<td>
<p>{{ object.section }}</p>
</td>
<td>
<p>{{ object.quantity }}</p>
</td>
<td>
<p>{{ object.description }}</p>
</td>
<td>
<p>{{ object.reception_date }}</p>
</td>
</tr>
The object.something are imported from a JSON file using
<script>
import objects from "./Database/Objects.json";
</script>
You would probably have to set some data information in the data() section
searchQuery: ""

Determine all attributes of a Javascript variable accessed inside a function WITHOUT running it

Is there a clever way to figure out all attributes of an object referenced within a function WITHOUT executing it?
For example let's say I have the following function:
var fun = function(a){
a.text = "hello world";
a.title = "greetings";
a.ran = "fun";
}
I would like some magical function that does:
var results = magical_function(fun, {});
// results = ["text", "title", "ran"];
Basically it's returning all attributes of the argument object that will be accessed inside the fun function, WITHOUT having to actually execute fun.
I said "without running" it because I don't want the act of checking this affect any outside app logic, but I am fine as long as the checking doesn't influence the outside world.
function.toString() is going to return a parsable string. Use Regex on that.
var fun = function(a){
a.text = "hello world";
a.title = "greetings";
a.ran = "fun";
}
var fun2 = function(x){
x.text = "hello world";
x.title = "greetings";
a.ran = "fun";
}
function magical_function(func) {
var data = func.toString();
var r = /a\.([a-z]+)/g;
var matches = [];
var match;
while ((match = r.exec(data)) != null) {
matches.push(match[1]);
}
return matches;
}
function magical_function_2(func) {
var data = func.toString();
var attribute_finder_r = new RegExp('function \\(([a-z]+)\\)');
var attribute_name_match = attribute_finder_r.exec(data);
if (!attribute_name_match) {
throw 'Could not match attribute name';
}
var attribute_name = attribute_name_match[1];
var r = new RegExp(attribute_name + '.([a-z]+)', 'g');
var matches = [];
var match;
while ((match = r.exec(data)) != null) {
matches.push(match[1]);
}
return matches;
}
console.log(magical_function(fun));
console.log(magical_function_2(fun2));
var myObj = {
text: '',
title: '',
ran: ''
}
var fun = function(a){
a.text = "hello world";
a.title = "greetings";
a.ran = "fun";
}
function magical_function(func, obj) {
var data = func.toString();
var keys = Object.keys(obj);
var regExp = '';
for (let i= 0; i < keys.length; i++) {
if (keys.length > 1 && ((i+1) < keys.length)) {
regExp += keys[i] + '|';
}
else if (keys.length == 1 || ((i+1) == keys.length)) {
regExp += keys[i];
}
}
regExp = '\.(['+ regExp +']+)\\s*=';
var r = new RegExp(regExp, 'g');
var matches = [];
var match;
while ((match = r.exec(data)) != null) {
if (Object.keys(obj).includes(match[1]))
matches.push(match[1]);
}
return matches;
}
console.log(magical_function(fun, myObj));
There's no way those attributes are going to get set before running the function.
The only thing you can do is to write another version of the function which only accesses the object passed and returns the result.

Limiting length of each word in a string

Is there a way to limit the length of each word in a string?
For example:
Loop through each word in a string
If a word is longer than X amount of characters, display a pop up message and do not submit the form.
Edit: My final code:
$("#comment-form").submit(function(event) {
var str = $("#comment-box").val(), limit = 135;
var wordList = str.split(' ');
$(wordList).each(function(i, word) {
if(word.length > limit) {
alert("Your comment has a string with more than " + limit + " characters. Please shorten it.");
event.preventDefault();
}
});
});
Try this:
var str = "This is the test string that contains some long words";
var wordList = str.split(' ');
var limit = 4;
$(wordList).each(function(i, word){
if(word.length >= limit){
alert(word);
}
});
You can use the following function
<script>
var string = "Please be sure question to answer the question";
function checkWordLength(string)
{
var string_array = string.split(" ");
for(var i=0; i<string_array.length; i++)
{
var word = string_array[i];
var word_length = word.length;
if(word_length>6) return false;
}
}
checkWordLength(string);
</script>
jsFiddle
function CheckString(string, character_limit)
{
var word = /\w+/igm;
var match;
while((match = word.exec(string)) !== null) {
if(match[0].length > character_limit)
{
alert(match[0]);
return false;
}
}
return true;
}
var character_limit = 5;
var string = 'this is a string of words and stuff even';
CheckString(string, character_limit);
This example uses regular expressions when it returns false make sure to either return false from the onSubmit method of your form.

Convert text items to JSON

I have a text that includes mani list items on the next format:
var text = "<li>M3-2200 (da2/M3-2200)</li><li>N3-2200 (da2/N3-2200)</li><li>Picasso (picasso/A500)</li><li>Picasso (picasso/A501)</li><li>Picasso (ventana/A500)</li>..."
I'm trying to create JSON on the next format:
{
name: "M3-2200",
Model: "M3-2200"
}
I'm trying using next code, but it doesn't work my problem is on push. anybody can explain me how do it right?
result ={};
while(text.indexOf("<li>")!== -1){
var listi = text.substring(text.indexOf("<li>"), text.indexOf("</li>"));
var model = listi.substring(0, listi.indexOf("(") -1);
var name = listi.substring(listi.indexOf("("), listi.indexOf(")"));
var item = {name: name: model : model};
result.push(item);
var text = text.substring(text.indexOf("</li>"));
}
Other solution for your problem:
var text = "<li>M3-2200 (da2/M3-2200)</li><li>N3-2200 (da2/N3-2200)</li><li>Picasso (picasso/A500)</li><li>Picasso (picasso/A501)</li><li>Picasso (ventana/A500)</li>";
var result = JSON.parse('[' +
text.replace(/(<li>|<\/li>| \(|\))/g, function(_, part){
switch (part) {
case '<li>': return '{"name":"';
case '</li>': return '},';
case ' (': return '", "Model":"';
case ')': return '"';
}
}) + '0]').slice(0, -1);
var text = "<li>M3-2200 (da2/M3-2200)</li><li>N3-2200 (da2/N3-2200)</li><li>Picasso (picasso/A500)</li><li>Picasso (picasso/A501)</li><li>Picasso (ventana/A500)</li>";
JSONStr = text.trim().replace(/<li>/g,"{\"name\":\"").replace(/ \(/g,"\" , \"model\":\"").replace(/\)\<\/li\>/g,"\"},");
JSONStr = "["+JSONStr.substring(0,JSONStr.length-1)+"]";
console.log(JSONStr);
Will the above code work?
I hope I understand your question correctly. If this is the output you want:
[{"name":"M3-2200 ","model":"da2/M3-2200"},{"name":"N3-2200 ","model":"da2/N3-2200"},{"name":"Picasso ","model":"picasso/A500"},{"name":"Picasso ","model":"picasso/A501"},{"name":"Picasso ","model":"ventana/A500"}]
Then this is a way to do it:
var text = "<li>M3-2200 (da2/M3-2200)</li><li>N3-2200 (da2/N3-2200)</li><li>Picasso (picasso/A500)</li><li>Picasso (picasso/A501)</li><li>Picasso (ventana/A500)</li>";
var extractItem = function (item) {
var partsArray = /(.+) ?\((.+)\)\<\/li>/.exec(item)
if(partsArray) return {"name":partsArray[1], "model":partsArray[2]}
}
var result = text.split('<li>')
.map(extractItem)
.filter(function(e){return e != undefined});
console.log(JSON.stringify(result));

Categories