Replace accented characters with their unaccented equivalent - javascript

I have a text field that can not allow accents. I was using this code:
<input type="text" onkeyup="value=value.replace(/[^0-9a-zA-Z' ']/g,'')">
But rather than blocking the characters, I need them to be replaced for example by typing Ç change to C
I found a function and hes working, but when I type a dot appears the letter A
Can you help me?
<script>function retiraAcento(palavra,obj){
com_acento = 'áàãâäéèêëíìîïóòõôöúùûüçÁÀÃÂÄÉÈÊËÍÌÎÏÓÒÕÖÔÚÙÛÜÇ<,>´`-,*/~';
sem_acento = 'aaaaaeeeeiiiiooooouuuucAAAAAEEEEIIIIOOOOOUUUUC ';
nova='';
for(i=0;i<palavra.length;i++) {
if (com_acento.search(palavra.substr(i,1))>=0) {
nova+=sem_acento.substr(com_acento.search(palavra.substr(i,1)),1);
} else {
nova+=palavra.substr(i,1);
}
}
obj.value = nova;}</script><input type="text" onKeyUp="javascript:retiraAcento(this.value, this);">

I didn't dig into it enough to see why the . was being replaced with A, but this version doesn't have that behaviour. It doesn't work exactly the same and it operates on the whole string, but that likely isn't a problem unless it's used in a large textfield, in which case it could be optimised other ways.
const com_acento = 'áàãâäéèêëíìîïóòõôöúùûüçÁÀÃÂÄÉÈÊËÍÌÎÏÓÒÕÖÔÚÙÛÜÇ<,>´`-,~';
const sem_acento = 'aaaaaeeeeiiiiooooouuuucAAAAAEEEEIIIIOOOOOUUUUC ';
function retiraAcento(string) {
return string
.split('')
.map(char => {
const charIdx = com_acento.indexOf(char)
if (charIdx !== -1) {
return sem_acento[charIdx]
}
return char
})
.join('')
}
function replaceCharOnChange(evt) {
event.target.value = retiraAcento(evt.target.value)
}
document.querySelector('input').addEventListener('keyup', replaceCharOnChange)
Apologies it's half rewritten in english! I'd also look into using another data structure than the two same-length strings. The simplest would be an object lookup table eg:
{á: 'a', ç: 'c', ...}
but there's other ways you could go about it too

Related

I am trying to solve this problem: Write a function onlyLetters that takes a string and returns a new string with the numbers filtered out

I am having some issues solving this problem, and would appreciate if someone could provide guidance on the best way to go about solving it. Thank You.
Write a function onlyLetters that takes a string and returns a new string with the numbers filtered out.
Examples:
onlyLetters('12ab') // => 'ab'
onlyLetters('1xz015')// => 'xz'
onlyLetters('1aasf123ql') // => 'aasfql'
Here is what I wrote:
function onlyLetters(str) {
if(str === isNaN === true) {
return str;
}
}
onlyLetters('12ab');
function onlyLetters(input) {
/*
*Check for characters 0->9 globally in a regex check
*and replace them to '' or nothing.
*/
return input.replace(/[0-9]/g, '');
}
/*
* Single line solution (if necessary)
* let onlyLetters = (input) => input.replace(/[0-9]/g, '');
*/
console.log(onlyLetters('12ab')); // => 'ab'
console.log(onlyLetters('1xz015')); // => 'xz'
console.log(onlyLetters('1aasf123ql')); // => 'aasfql'
How about something as simple as replace? It may be too simple and for that maybe ask another question?

string containing equals "=" and no quotes convert to JSON

Im currently stuck trying to convert a string into JSON in javascript.
the string im getting from the server is:
"{knee=true, centered=true}"
the outcome im looking for is something like this:
{ knee: true, centered: true}
but since the string is using equals and there are missing quotes the JSON.parse isnt working, I dont know how to solve this. any help will be appreciated, thank you!
The best I could do was this ... It returns value of object in strings though it seems to work perfect ! ( Actually this one challenged me so I had to do it ) :-)
let str = "{knee = true, centered = true}";
str = str.replaceAll('{', '')
str = str.replaceAll('}', '')
str = str.split(",")
str = Object.assign({}, str);
let key_value;
let key;
let val;
for (var i = 0; i < Object.keys(str).length; i++) {
key_value = str[i].split("=");
key = String(key_value[0]);
val = key_value[1];
str[i] = val;
delete Object.assign(str, {[key]: str[i]
})[i];
}
console.log(str)
Assuming you don't have nested things or strings with commas or brackets in them, you could replace all { with {", = with ":, and , with , ":
const str = "{knee=true, centered=true}"
console.log(
JSON.parse(str.split('{').join('{"').split('=').join('":').split(', ').join(', "'))
)
Without more specifics it's impossible to verify how correct this is, but if I was to make some assumptions:
An object is a set of key/value pairs surrounded by { and }
Key/value pairs are separated by ,
Any arbitrary whitespace is allowed around key/value pairs
A key and value are separated by a =
Values can only hold the value true or false which should be translated to a JavaScript boolean
...then parsing can be done through some regular expressions and string manipulations.
const objectRegExp = /^\{(.*)}$/;
function parseNJson(str) { // notJSON
const match = objectRegExp.exec(str);
if (!match) {
throw new Error('This is not NJson');
}
const [, keyValuesBlock] = match;
const keyValueStatements = keyValuesBlock.split(',');
const keyValues = keyValueStatements.map(statement => statement.split('='));
return keyValues.reduce((result, [keyStr, valueStr]) => {
const key = keyStr.trim();
const trimmedValue = valueStr.trim();
let value;
if (trimmedValue === 'true') {
value = true;
} else if (trimmedValue === 'false') {
value = false;
} else {
throw new Error(`Unsupported value ${trimmedValue}`);
}
return Object.assign(result, { [key]: value });
}, {});
}
This will easily fall apart if any assumptions were incorrect, like "what if values can be strings? What if strings can be quoted with double quotes? What if they can also be surrounded by single quotes? What if numbers are supported? What if hexadecimal numbers are supported?"
If the data being sent on the server is a standard format, they should be able to tell you "this was formatted as X" so you can find a spec-compliant X parser. Or you could insist data is sent as JSON instead, since that's a super common exchange format. The best thing is that the server and client are using a common, well-defined message formatting spec so you don't accidentally break things whenever receiving or sending data that has characteristics you didn't account for.

.toLowerCase() / .toUpperCase() not working

I'm trying to get better at javascript through codewars.com katas, and I came across an exercice in which things like element[i]=element[i].toLowerCase() doesn't change anything at all.
I would like to have some help with my code, here is the exercice's instructions followed by my code:
(Please note that I'm not very experienced with JS so the code may not be perfect at all)
A string is considered to be in title case if each word in the string
is either:
(a) capitalised (that is, only the first letter of the word
is in upper case) or
(b) considered to be an exception and put entirely into lower case unless it is the first word, which is always capitalised.
Write a function that will convert a string into title case, given an optional list of exceptions (minor words). The list of minor words will be given as a string with each word separated by a space.
Your function should ignore the case of the minor words string -- it should behave in the same way even if the case of the minor word string is changed.
Arguments:
First argument (required): the original string to be converted.
Second argument (optional): space-delimited list of minor words that must always be lowercase except for the first word in the string. The JavaScript/CoffeeScript tests will pass undefined when this argument is unused.
function titleCase(title, minorWords) {
if(title.length==0){return ""}
var titlesplit = title.split(" ")
if(minorWords){
minorWords=minorWords.split(" ")
}
var solutionstring = ""
titlesplit.forEach(element => myfunction(element,minorWords))
solutionstring[0] = solutionstring[0].toUpperCase()
return solutionstring
function myfunction(element,minorWords){
var elementlength= element.length
var i=0
if(minorWords && minorWords.includes(element)){
for(i;i<elementlength;i++){
element[i]=element[i].toLowerCase()
}
}else {
for(i;i<elementlength;i++){
if(i==0){element[i]=element[i].toUpperCase()}
else{element[i]=element[i].toLowerCase()}
}
}
if(solutionstring.length==0){solutionstring=solutionstring+element}else{solutionstring=solutionstring+" "+element}
return
}
}
As pointed out in comments, Strings are immutable in JavaScript.
Additionally, for searching use Maps instead of includes.
Likewise you can see what Set in JavaScript is and easily use Set here.
Added comments for you better understanding.
function titleCase(title, minorWords) {
// Use === for comparison
// Prefer using curly braces even for single statements
if (title.length === 0) {
return "";
}
var titlesplit = title.split(" ");
// Maps/Objects give O(1) search compared to arrays O(n)
// Key,value pairs - similar to dictionary
var minorWordsMap = {};
minorWords.split(" ").forEach(i => minorWordsMap[i.toLowerCase()] = true);
var finalWords = titlesplit.map((element, index) => convertCase(element, index));
finalWords[0] = toPascalCase(finalWords[0]);
return finalWords.join(" ");
function toPascalCase(s) {
s = s.split("");
s[0] = s[0].toUpperCase();
return s.join("");
}
function convertCase(element, index) {
const lElement = element.toLowerCase();
// If element is part of exception words, ignore
if(index !== 0 && minorWordsMap[lElement]) {
return element;
}
// If first element or not in exception list, send Title case
return toPascalCase(lElement);
}
}

Filtering ranges of letters in Javascript

I have to create a program that takes the first letter of a prompt, and if that letter is between a and k, then it has to produce a certain output, if it's between l and p another and so on. Is there a way to do this without writing every letter of the alphabet down? (sorry I'm a new coder)
I think you should try to solve the problem, before asking - so you can show what you've already tried.
I think the snippet below points you in the right direction - but it takes any character, not just letters. You need to get everything filtered out that's not a lower case letter.
// UI elements
const input = document.getElementById('input1')
const result = document.getElementById('result')
// input event
// only the first character is taken into account
input.addEventListener('input', function(e) {
// adding the characters of the input value to an array, and
// picking the 0th element (or '', if there's no 0th element)
const a = [...this.value][0] || ''
let ret = ''
if (a !== '') {
// lowercaseing letters, so it's easier to categorize them
ret = categorizeAlphabet(a.toLowerCase().charCodeAt(0))
} else {
ret = 'The input is empty'
}
// displaying the result
result.textContent = ret
})
// you could use this function to filter and categorize
// according to the problem ahead of you - and return the result
// to be displayed.
// In this example this function is rather simple, but
// you can build a more complex return value.
const categorizeAlphabet = (chCode) => {
return `This is the character code: ${chCode}`
}
<label>
First character counts:
<input type="text" id='input1'>
</label>
<h3 id="result">The input is empty</h3>

javascript : How to filter text without spell checking?

The goal is to filter some "test" or "flood" messages in a shout box chat.
ex: when an user writes something like
aaaaaaaaaaaaaaaaaaaaa or jdhshjdskhdshuishifhduif or dsqjlkdsqjiodsqjiosqjdsjq
I want to filter such stupid words: I guess I need to write some functions like:
if string length>20 or string conatins more that 4 vowels in a row or contains 4 consonants in a row
or contains some special chars...
Maybe this function has aleardy been written to avoid reinventing the wheel.
regards
Well using some Regular Expressions could do the trick.
EDIT
I have updated the code after Chris's suggestion.
So the credit goes to him.
String.prototype.testVowels = function () {
return !(/([aeiou]){4,}\w*/g.test(this));
}
String.prototype.testConsonants = function () {
return !(/([bcdfghjklmnpqrstwxyz]){4,}\w*/g.test(this));
}
String.prototype.testLength = function() {
return this.length < 20;
}
function testString(str) {
var stringArr = str.split(" ");
// this will test for each word in the str parameter
stringArr.forEach(function(s) {
if(s.testConsonants() && s.testLength() && s.testVowels()) {
console.log("The word " + s + " is ok !");
}
});
}

Categories

Resources