How to change every character to opposite case in Javascript? - javascript

My HTML page is
<!DOCTYPE html>
<html>
<head>
<script>
function changeCase(){
var str=document.getElementById("changeCase").innerHTML;
for(var i=0;i<str.length;i++){
if(str.charAt(i)==''){
console.log("-------------------------");
}
else if(str.charAt(i)===str.charAt(i).toLowerCase()){
str.charAt(i).toUpperCase();
}
else if(str.charAt(i)===str.charAt(i).toUpperCase()){
str.charAt(i).toLowerCase()
}
}
console.log(str,"after");
}
</script>
</head>
<body>
<div style="width:400px;margin:30px auto 0px;">
<p id="changeCase">
Part Of Me Suspects That I'm a Loser, And The Other Part of Me Thinks I'm God Almighty.
</p>
<p><button type="button" onclick="changeCase()">Click Here</button></p>
</div>
</body>
</html>
I want to change the case of the characters in paragraph to their opposite i.e uppercase to lowercase and vice versa...
How this could be achieved?

Strings are immutable, they don't change when using methods like toLowerCase(), they return a new string that is changed, and you have to assign that new string to something :
function changeCase() {
var str = document.getElementById("changeCase").innerHTML,
str2 = '';
for (var i = 0; i < str.length; i++) {
if (str.charAt(i) === str.charAt(i).toLowerCase()) {
str2 += str.charAt(i).toUpperCase();
} else if (str.charAt(i) === str.charAt(i).toUpperCase()) {
str2 += str.charAt(i).toLowerCase()
} else {
str2 += str.charAt(i);
}
}
console.log(str2, "after");
}
FIDDLE

let str = "The Quick Brown Fox";
const newStr = str
.split("")
.map(c => (c === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase()))
.join("");
console.log(newStr);

Here's an elegant (although a bit advanced) solution:
"AbCdEf".replace(/([a-z]+)|([A-Z]+)/g, function(_, low, up) {
return low ? low.toUpperCase() : up.toLowerCase()
})

Use the new ES6 spread operator: more info at MDN
// es6 arrow functions
// does this character === the lowercase version of itself? If so, it is lowercase
// this function returns either true or false
const isLowerCase = char => char.toLowerCase() === char;
// another arrow function
// implements a ternary operator (x ? y : z). If x is true return y, else return z
// if the char is lowercase, make it uppercase, else make it lowercase
const swapCase = char => isLowerCase(char) ? char.toUpperCase() : char.toLowerCase();
// ES6 let keyword
// arrow function
// ES6 spead operator [...string] returns an array with each letter in string
// as an element, for every element (char), we run the swapCase func
// to get the opposite case, then join it all back into a string
let alternateCase = string => {
return [...string].map(swapCase).join('');
};

Solution with regexp is more readable in my opinion:
function toOppositeCase(char) {
return (/[a-z]/).test(char) ? char.toUpperCase() : char.toLowerCase();
}
var str = "soMeStrinG",
str1 = "";
for (var i = 0; i < str.length; i++) {
str1 += toOppositeCase(str[i]);
}
console.log(str1);

You can store the new string in a variable like this -
function changeCase(){
var str=document.getElementById("changeCase").innerHTML;
var newStr = "";
for(var i=0;i<str.length;i++){
if(str.charAt(i)==''){
console.log("-------------------------");
}
else if(str.charAt(i)===str.charAt(i).toLowerCase()){
newStr += str.charAt(i).toUpperCase();
}
else if(str.charAt(i)===str.charAt(i).toUpperCase()){
newStr += str.charAt(i).toLowerCase()
}
}
console.log(str,"after");
document.getElementById("changeCase").innerHTML = newStr;
}

One more option for change case of strings :
<!DOCTYPE html>
<html>
<head>
<script>
function changeCase(){
var element = document.getElementById("changeCase"),
str=element.innerHTML,
str_new = '';
for(i=0; i<str.length;i++){
if(str[i] >= 'a' && str[i] <= 'z') {
str[i].toUpperCase();
str_new += str[i].toUpperCase();
}
else if(str[i] >= 'A' && str[i] <= 'Z') {
str[i].toLowerCase();
str_new += str[i].toLowerCase();
}
else str_new += str[i].toLowerCase();
}
console.log(str_new, "after");
element.innerHTML = str_new;
}
</script>
</head>
<body>
<div style="width:400px;margin:30px auto 0px;">
<p id="changeCase">Part Of Me Suspects That I'm a Loser, 123456789 And The Other Part of Me Thinks I'm God Almighty.</p>
<p><button type="button" onclick="changeCase()">Click Here</button></p>
</div>
</body>
</html>

function changeCase(str) {
var changed = '';
for (var i = 0; i < str.length; i++) {
var char = str.charAt(i);
var charCodeInt = char.charCodeAt(0);
if (charCodeInt >= 97 && charCodeInt <= 122) {
changed += char.toUpperCase();
} else if (charCodeInt >= 65 && charCodeInt <= 90) {
changed += char.toLowerCase()
}else changed += char;
}
return changed
}

function flipChar(char) {
const lowercasePat = /[a-z]/;
if(lowercasePat.test(char)) {
return char.toUpperCase();
} else {
return char.toLowerCase();
}
}
function flipCharacters(str) {
const strLen = str.length;
let flippedStr = '';
let char;
for(let i = 0; i < strLen; i++) {
char = str.charAt(i);
flippedStr += flipChar(char);
}
return flippedStr;
}
console.log(flipCharacters('SuReN')); // sUrEn

Related

How to use String.prototype as a function in React JS

I want to use Kolner phonetic for my app but I dont know how to use that like a function. Here are two files and for that reason I need to use that like hooks or like function.
The first block of code is the algorithm for phonetic and the second is the implementation.
String.prototype.colophonetics = (function(){
var substitution = {'ä': 'a', 'ö': 'o', 'ü': 'u', 'ß': 'ss', 'ph': 'f'}
var exceptions_leading = {
4: ["ca","ch","ck","cl","co","cq","cu","cx"],
8: ["dc","ds","dz","tc","ts","tz"]
};
var exceptions_following = ["sc","zc","cx","kx","qx"];
var coding_table = {
0: "aeijouy",
1: "bp",
2: "dt",
3: "fvw",
4: "cgkq",
48: "x",
5: "l",
6: "mn",
7: "r",
8: "csz"
};
if(Array.prototype.contains === undefined){
Array.prototype.contains = function(element){
for (var i = 0; i < this.length; ++i) {
if (this[i] == element) {
return true;
}
}
return false;
}
}
return function(word){
var word = word || this + "";
if(typeof word === 'string' && word.indexOf(' ') !== -1){
word = word.split(' ');
}
if(typeof word === 'object'){
var phons = [];
for(i in word){
phons.push(arguments.callee(word[i]));
}
return phons.join(' ');
}
if(typeof word !== 'string'){
return '';
}
word = word.toLowerCase();
for(s in substitution){
word = word.replace(new RegExp(s, "g"), substitution[s]);
}
var value = [];
var length = word.length;
for(var i = 0; i < length; i++){
var l = word.substr(i, 1);
value[i] = '';
if(i === 0 && length > 1 && word[i] + word[i+1] === 'cr'){
value[i] = 4;
}
for(code in exceptions_leading){
if(exceptions_leading[code].contains(word[i] + word[i+1])){
value[i] = parseInt(code);
}
}
if(i !== 0 && exceptions_following.contains(word[i-1] + word[i])){
value[i] = 8;
}
if(value[i] == ''){
for(code in coding_table){
if(coding_table[code].indexOf(l) !== -1){
value[i] = parseInt(code);
break;
}
}
}
}
for(var i = 1; i < length; i++){
if(value[i] == value[i-1]){
value[i] = "";
}
if(value[i] == 0){
value[i] = "";
}
}
return value.join('') + "";
}
})();
I need like this to use in React JS because the main problem is I am new with React.
<html>
<head>
<script type="text/javascript" charset="utf-8" src="../colophonetics.js"></script>
</head>
<script type="text/javascript" charset="utf-8">
var string = "Rønne Ronne Ranne Runne Ramme";
document.write(string + ": " + string.colophonetics() + "<br/>");
</script>
</html>

Encode letter to number

I feel like I am failing everything this semester. but I was wondering if you all could help me with a JS project. We have been tasked with essentially converting numbers to letters and vica versa using textareas in HTML. I was able to do the numbers to letters function, but am having difficulties going the other way. what I have for all is:
var $ = function(id) {
return document.getElementById(id);
};
window.onload = function() {
$("btnDecode").onclick = fnDecode;
$("btnEncode").onclick = fnEncode;
$("btnClear").onclick = fnClear;
};
function fnDecode() {
var msg = $("textin").value;
if (msg === "") {
$("textin_span").innerHTML = "* Please enter a message to decode *";
$("textin").focus;
return;
} else {
$("textin_span").innerHTML = "";
}
var nums = msg.split(",");
var outstr = "";
for(var i=0; i < nums.length; i++) {
var n2 = parseInt(nums[i]);
if (isNaN(n2)) {
outstr += "?";
} else if (isNallN(nums[i])) {
} else if (n2 === 0) {
outstr += " ";
} else if (n2 < 1 || n2 > 26) {
outstr += "?";
} else {
outstr += String.fromCharCode(n2+64);
}
$("textout").value = outstr;
}
}
function isNallN(s) {
//parse string to check all characters are digits
}
function fnEncode() {
var msg = $("textin").value.toUpperCase();
$("textin").value = msg;
if (msg === "") {
$("textin_span").innerHTML = "* Please enter numberse to decode *";
$("textin").focus;
return;
} else {
$("textin_span").innerHTML = "";
}
var c;
var outstr = "";
for (var i=0; i<msg.length; i++);
c = msg.charCodeAt(i);
if (typeof c === "number") {
outstr += "99";
}else if (c === " ") {
outstr += 0;
/*} else if (c[i] >= "A" && c[i] <= "Z") {
outstr += "99";*/
} else {
outstr += String.charCodeAt(c - 64);
}
$("textout").value = outstr;
//var x = msg.charAT(i);
}
obviously isNallN is not complete, but he promised us if we could figure out fnEncode we should be able to do isNallN with no issues (which I am hoping is true lol) What am doing wrong though in fnEncode? Every time I run it, it gives me "99" even when I put letters in.

javascript get element unique selector

I am moving elements using javascript and I need to create a logic for the combinations happening during the drag/drops
I'm trying to get details from the elements, a CSS like selector could be also good, but dunno if it is possible.. (like copy-selector in chrome dev tools)
document.onmouseup = function(e){
targetDest = e.target;
//console.log('targetDest: ', targetDest);
let
indexA = Array.from(targetCurr.parentNode.children).indexOf(targetCurr),
indexB = Array.from(targetDest.parentNode.children).indexOf(targetDest);
console.log(indexA, indexB);
if(targetDest != targetCurr){
if(targetDest == document.documentElement){
console.log('document');
}
else if(targetDest == undefined){
console.log('undefined');
}
else if(!targetDest){
console.log('!dest');
}
else if(targetDest == null){
console.log('null');
}
else if(targetDest == false){
console.log('false');
}
else{
console.log('else');
//targetCurr.parentNode.insertBefore(targetDest, targetCurr);
//console.log('...');
}
}else{
console.log('itself');
}
}
Keep in mind that this will not necessarily uniquely identify elements. But, you can construct that type of selector by traversing upwards from the node and prepending the element you're at. You could potentially do something like this
var generateQuerySelector = function(el) {
if (el.tagName.toLowerCase() == "html")
return "HTML";
var str = el.tagName;
str += (el.id != "") ? "#" + el.id : "";
if (el.className) {
var classes = el.className.split(/\s/);
for (var i = 0; i < classes.length; i++) {
str += "." + classes[i]
}
}
return generateQuerySelector(el.parentNode) + " > " + str;
}
var qStr = generateQuerySelector(document.querySelector("div.moo"));
alert(qStr);
body
<div class="outer">
div.outer
<div class="inner" id="foo">
div#foo.inner
<div class="moo man">
div.moo.man
</div>
</div>
</div>
I wouldn't suggest using this for much besides presenting the information to a user. Splitting it up and reusing parts are bound to cause problems.
My solution using :nth-child:
function getSelector(elm)
{
if (elm.tagName === "BODY") return "BODY";
const names = [];
while (elm.parentElement && elm.tagName !== "BODY") {
if (elm.id) {
names.unshift("#" + elm.getAttribute("id")); // getAttribute, because `elm.id` could also return a child element with name "id"
break; // Because ID should be unique, no more is needed. Remove the break, if you always want a full path.
} else {
let c = 1, e = elm;
for (; e.previousElementSibling; e = e.previousElementSibling, c++) ;
names.unshift(elm.tagName + ":nth-child(" + c + ")");
}
elm = elm.parentElement;
}
return names.join(">");
}
var qStr = getSelector(document.querySelector("div.moo"));
alert(qStr);
body
<div class="outer">
div.outer
<div class="inner" id="foo">
div#foo.inner
<div class="moo man">
div.moo.man
</div>
</div>
</div>
Please note it won't return the whole path if there's an element with ID in it - every ID should be unique on the page, as valid HTML requires.
I use output of this function in document.querySelector later in the code, because I needed to return focus to the same element after replaceChild of its parent element.
I hope CollinD won't mind I borrowed his markup for the code snippet :-)
I mixed the 2 solutions proposed to have a result readable by humans and which gives the right element if there are several similar siblings:
function elemToSelector(elem) {
const {
tagName,
id,
className,
parentNode
} = elem;
if (tagName === 'HTML') return 'HTML';
let str = tagName;
str += (id !== '') ? `#${id}` : '';
if (className) {
const classes = className.split(/\s/);
for (let i = 0; i < classes.length; i++) {
str += `.${classes[i]}`;
}
}
let childIndex = 1;
for (let e = elem; e.previousElementSibling; e = e.previousElementSibling) {
childIndex += 1;
}
str += `:nth-child(${childIndex})`;
return `${elemToSelector(parentNode)} > ${str}`;
}
Test with:
// Select an element in Elements tab of your navigator Devtools, or replace $0
document.querySelector(elemToSelector($0)) === $0 &&
document.querySelectorAll(elemToSelector($0)).length === 1
Which might give you something like, it's a bit longer but it's readable and it always works:
HTML > BODY:nth-child(2) > DIV.container:nth-child(2) > DIV.row:nth-child(2) > DIV.col-md-4:nth-child(2) > DIV.sidebar:nth-child(1) > DIV.sidebar-wrapper:nth-child(2) > DIV.my-4:nth-child(1) > H4:nth-child(3)
Edit: I just found the package unique-selector
Small improvement of the #CollinD answer :
1/ Return value when the selector is unique
2/ Trim classes value (classes with end blanks make errors)
3/ Split multiple spaces between classes
var getSelector = function(el) {
if (el.tagName.toLowerCase() == "html")
return "html";
var str = el.tagName.toLowerCase();
str += (el.id != "") ? "#" + el.id : "";
if (el.className) {
var classes = el.className.trim().split(/\s+/);
for (var i = 0; i < classes.length; i++) {
str += "." + classes[i]
}
}
if(document.querySelectorAll(str).length==1) return str;
return getSelector(el.parentNode) + " > " + str;
}
Based on previous solutions, I made a typescript solution with a shorter selector and additional checks.
function elemToSelector(elem: HTMLElement): string {
const {
tagName,
id,
className,
parentElement
} = elem;
let str = '';
if (id !== '' && id.match(/^[a-z].*/)) {
str += `#${id}`;
return str;
}
str = tagName;
if (className) {
str += '.' + className.replace(/(^\s)/gm, '').replace(/(\s{2,})/gm, ' ')
.split(/\s/).join('.');
}
const needNthPart = (el: HTMLElement): boolean => {
let sib = el.previousElementSibling;
if (!el.className) {
return true;
}
while (sib) {
if (el.className !== sib.className) {
return false;
}
sib = sib.previousElementSibling;
}
return false;
}
const getNthPart = (el: HTMLElement): string => {
let childIndex = 1;
let sib = el.previousElementSibling;
while (sib) {
childIndex++;
sib = sib.previousElementSibling;
}
return `:nth-child(${childIndex})`;
}
if (needNthPart(elem)) {
str += getNthPart(elem);
}
if (!parentElement) {
return str;
}
return `${elemToSelector(parentElement)} > ${str}`;
}

How to remove space from RiTa.js random word generator?

I'm working on a word generator inspired by Daniel Shiffman's demo of the RiTa library. Right now, the code adds a space between all words and punctuation using the line:
output += " ";
I have been trying to figure out how to change the code so that space does not appear between punctuation (such as periods) and words. I think the simplest way to do this would be to use an if/else statement that leaves punctuation unaltered but adds space to words, but I am having a hard time figuring out what functions from the Rita library to use for this, as well as the syntax.
Any ideas? Here's my code right now:
var input;
var button;
var lexicon;
function setup() {
noCanvas();
lexicon = new RiLexicon();
input = createInput('As I say a noun is the name of a thing.');
button = createButton('submit');
input.changed(processRita);
button.mousePressed(processRita);
input.size(400);
}
function processRita() {
var s = input.value();
var rs = new RiString(s);
var words = rs.words();
var pos = rs.pos();
console.log(words);
console.log(pos);
var output = '';
for (var i = 0; i < words.length; i++) {
if (/nn.*/.test(pos[i])) {
var alliterations = lexicon.alliterations(words[i]);
if(alliterations.length == 0){
output+=words[i];
}else{
output += alliterations[Math.floor(Math.random() * alliterations.length)];
}
//console.log("noun");
//console.log(alliterations.length);
} else if (/jj.*/.test(pos[i])) {
var alliterations = lexicon.alliterations(words[i]);
output += alliterations[Math.floor(Math.random() * alliterations.length)];
//console.log("adjective");
} else if (/vb/.test(pos[i])) {
var alliterations = lexicon.alliterations(words[i]);
output += alliterations[Math.floor(Math.random() * alliterations.length)];
//console.log("verbs");
}
else {
//console.log(words[i]);
output += words[i];
} {
output += " ";
}
}
createP(output);
}
Why do you need a library for this? Can't you just use the regular String functions to test whether a String is a punctuation mark?
You could just use a regular expression to test whether a String matches a punctuation character. Or just use a series of equality checks against each punctuation mark you care about.
You might also check out the startsWith() function and the endsWith() function.
after much trial and error, I had help from a coding professor who helped me to solve this problem, which was more complicated than I originally anticipated. In order to get this code to work, we added this bit toward the beginning of the for loop:
if(words[i] == "." || words[i] == "," || words[i] == "?" || words[i] == "!"){
output += words[i];
}else{
output += " ";
So the entire code now looks like this:
for (var i = 0; i < words.length; i++) {
if(words[i] == "." || words[i] == "," || words[i] == "?" || words[i] == "!"){
output += words[i];
}else{
output += " ";
if (/nn.*/.test(pos[i])) {
var alliterations = lexicon.alliterations(words[i]);
if(alliterations.length == 0){
output+=words[i];
}else{
output += alliterations[Math.floor(Math.random() * alliterations.length)];
}
//console.log("noun");
//console.log(alliterations.length);
} else if (/jj.*/.test(pos[i])) {
var alliterations = lexicon.alliterations(words[i]);
output += alliterations[Math.floor(Math.random() * alliterations.length)];
//console.log("adjective");
} else if (/vb/.test(pos[i])) {
var alliterations = lexicon.alliterations(words[i]);
output += alliterations[Math.floor(Math.random() * alliterations.length)];
//console.log("verbs");
}
else {
//console.log(words[i]);
output += words[i];
}
}
}
createP(output);
}
Its much simpler if you use the RiTa library functions:
function processRita() {
var all, output = [],
words = RiTa.tokenize(input.value()),
pos = RiTa.getPosTags(words);
for (var i = 0; i < words.length; i++) {
if (/[nn|kk|vb|jj].*/.test(pos[i]) && (all = lexicon.alliterations(words[i])).length) {
output.push(RiTa.randomItem(all));
} else {
output.push(words[i]);
}
}
createP(RiTa.untokenize(output));
}

Nothing happens after Prompt

Sorry, I wasn't clear enough. I need it to list all the numbers from 0 to the number inputted by the prompt into the HTML. I made some suggested changes but now I only get the result for the specific number inputted, not all the numbers up to that number. I am just starting out so please be gentle. Thanks!
$(function() {
var number = parseInt(prompt("Let me see a number:"));
var result;
for(var i = 0; i <= number; i++) {
if ( i %15 == 0) {
result = "Ping-Pong";
}
else if (i %5 == 0) {
result = "Pong";
}
else if (i %3 == 0) {
result = "Ping";
}
else {
result = number;
}
document.getElementById("show").innerHTML = result;
};
});
You can do either:
for(var i = 0; i <= number; i++) {
var digit = number[i]; // or any other assigment to new digit var
if ( digit % 5 == 0) {
return "Ping-Pong";
}
.... rest of your code here.
or
if ( number % 5 == 0) {
return "Ping-Pong";
}
.... rest of your code here.
Problem is you did nothing after the return keyword. Also you didn't declared variable as digit. I hope this is what you are looking for.
With loop:
$(function() {
var number = parseInt(prompt("Let me see a number:"));
var result;
for (var i = 0; i <= number; i++) {
if (i % 15 == 0) { // replaced `digit` with `i`
result = "Ping-Pong";
} else if (i % 5 == 0) {
result = "Pong";
} else if (i % 3 == 0) {
result = "Ping";
} else {
result = number;
}
alert(result);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
Without loop:
$(function() {
var number = parseInt(prompt("Let me see a number:"));
var result;
if (number % 15 == 0) { // replaced `digit` with `number`
result = "Ping-Pong";
} else if (number % 5 == 0) {
result = "Pong";
} else if (number % 3 == 0) {
result = "Ping";
} else {
result = number;
}
alert(result);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
Ok, I figured it out. For future reference, this is what I was trying to do:
$(function() {
var number = parseInt(prompt("Let me see a number:"));
var i
var text = "";
for(i = 1; i <= number; i++) {
if ( i %15 == 0) {
text += "<br>" + "Ping Pong" + "<br>";
}
else if (i %5 == 0) {
text += "<br>" + "Pong" + "<br>";
}
else if (i %3 == 0) {
text += "<br>" + "Ping" + "<br>";
}
else {
text += "<br>" + i + "<br>";
}
};
document.getElementById("show").innerHTML = text;
});

Categories

Resources