I have written a code that finds two strings and in return it should tell me if these two strings are existing:
function searchTwoString(data, str1, str2) {
var strX = str1 + " " + strValueX + "\r\n";
var strY = str2 + " " + strValueY;
var strValueX;
var strValueY;
for (var i = 0; i < data.length; i++) {
if (data[i] === str1) {
var strValueX = " exist";
continue;
} else if (data[i] === str2) {
var strValueY = " exist";
break;
}
}
return strX + strY;
}
Achieved result:
str1 undefined
str2 undefined
Expected result:
str1 exist
str2 exist
it tells me my strvalueX & strvalueY are undefined isn't it i have already gave the values in the if statement?
thanks to those who will help out
Here is an answer to your question with comment.
Hope you understand what I'm talking about.
function searchTwoString(data, str1, str2) {
var strX;// = str1 + " " + strValueX + "\r\n";
var strY;// = str2 + " " + strValueY;
var strValueX;
var strValueY;
for (var i = 0; i < data.length; i++) {
if (data[i] === str1) {
// var strValueX = " exist";
// do not define again
strValueX = " exist";
continue;
} else if (data[i] === str2) {
// var strValueY = " exist";
// do not define again
strValueY = " exist";
break;
}
}
// define the value here after strValueX and strValueY is set
strX = str1 + " " + strValueX + "\r\n";
strY = str2 + " " + strValueY;
return strX + strY;
}
The order of your statements is off. In lines 2 and 3, you are using strValueX and strValueY before they are defined. Lines 2 and 3 should be moved to before the return so that they will have the updated values.
I believe there is also a shadowing problem, as in the if statements you are creating new variables with the var keyword (e.g. var strValueX = " exist";). You will want to remove var from the if statements so that it updates the values of the outer variables.
Related
I'd like to write a JavaScript program that displays a symmetric histogram like this image:
The program should ask the user to enter the number of bars to print and the character to use to draw the bars. The count of characters in the bar needs to be displayed on the right-side of each bar.
The example showed is when I entered # as the character and 13 as the number.
Here's my code:
var symbol = prompt("Enter the symbol");
var number = prompt("Enter the number");
var currentNum = 1;
let text = "";
let symbolNum = symbol;
while (currentNum <= number) {
text += "<br>" + symbolNum + " " + currentNum;
symbolNum += symbol;
currentNum++;
}
document.write(text + "<br>");
And at last, I only can output the following:
I'd like to know what I can do in order to reverse the loop?
Try this
function SymmetricHistogram(){
const size = 10;
let numberX = 0;
let numberY = 0;
for(let i = size; i>=-size; i--) {
for(let j=size; j>=Math.abs(i); j--){
process.stdout.write("#");
}
numberX <=size ? console.log(numberX++) : console.log(--numberY);
}
}
SymmetricHistogram();
Or try the below
https://onecompiler.com/javascript/3x58bqr3h
Two different way for the same result. Not realy clean, but work.
var symbol = prompt("Enter the symbol");
var number = prompt("Enter the number");
var currentNum = 1;
let textTOP = "";
let textBOTTOM = "";
let symbolNum = symbol;
while (currentNum <= number) {
textTOP += "<br>" + symbolNum + " " + currentNum;
if (currentNum < number)
textBOTTOM = "<br>" + symbolNum + " " + currentNum + textBOTTOM;
symbolNum += symbol;
currentNum++;
}
document.write(textTOP + textBOTTOM + "<br>");
var symbol = '#';
var number = 13;
var currentNum = 1;
let text = "";
while (currentNum < number * 2) {
if (currentNum <= number) {
let num = currentNum;
text += "<br>" + symbol.repeat(num) + " " + num;
} else {
let num = Math.abs(number * 2 - currentNum);
text += "<br>" + symbol.repeat(num) + " " + num;
}
currentNum++;
}
document.write(text + "<br>");
I'm turning a string into an object, then looping over that object. For some reason, if the string is semi-correctly formatted and I don't do the first two steps (replacing the parentheses with curly brackets) it works fine.
However, the replacement puts single ' instead of " (although it still parses without error). The parse misses putting the second id underneath the employeeType, and mistakenly puts it under employee.
https://codepen.io/MrMooCats/pen/zwpQGa
var str = "(id,created,employee(id,firstname,employeeType(id),lastname),location)";
str = str.replace(/[(]/g, "{"); // Possible problem line?
str = str.replace(/[)]/g, "}"); // Possible problem line?
str = str.replace(/([A-z])\s*{/g, "$1\":{");
str = str.replace(/([A-z])\s*([},])/g, "$1\":null$2");
str = str.replace(/({)/g, "{\"");
str = str.replace(/(,)/g, ",\"");
var objectStr = JSON.parse(str); // Object created, but wrong
var objectOutput = function(obj, counter) {
for(var i in obj) {
console.log(Array(counter+1).join("-") + " " + i);
if(obj.hasOwnProperty(i)){
if (obj[i] != null) {
objectOutput(obj[i], counter+1);
} else {
counter = 0;
}
}
}
};
objectOutput(objectStr, 0);
Actual output:
" id"
" created"
" employee"
"- id"
" firstname"
" employeeType"
"- id"
" lastname"
" location"
Expected Output
" id"
" created"
" employee"
"- id"
"- firstname"
"- lastname"
"- employeeType"
"-- id"
" location"
To get desired output you need to fix your objectOutput functrion:
// Works fine if the ( are { instead and remove the first two lines
var str = "(id,created,employee(id,firstname,employeeType(id),lastname),location)";
str = str.replace(/[(]/g, "{"); // Possible problem line?
str = str.replace(/[)]/g, "}"); // Possible problem line?
str = str.replace(/([A-z])\s*{/g, "$1\":{");
str = str.replace(/([A-z])\s*([},])/g, "$1\":null$2");
str = str.replace(/({)/g, "{\"");
str = str.replace(/(,)/g, ",\"");
var objectStr = JSON.parse(str); // Object created, but wrong
var objectOutput = function(obj, counter) {
for (var i in obj) {
console.log(Array(counter + 1).join("-") + " " + i);
if (obj.hasOwnProperty(i)) {
if (obj[i] != null) {
objectOutput(obj[i], counter + 1);
}
}
}
};
objectOutput(objectStr, 0);
I would also change regex this way:
var str = "(id,created,employee(id,firstname,employeeType(id),lastname),location)";
str = str.replace(/\(/g, "{").replace(/\)/g, "}");
str = str.replace(/([_a-zA-Z][_a-zA-Z0-9]*)\s*([,{}])/g, function(m, name, x){
return '"'+name+'":' + (x != '{' ? 'null' : '') + x;});
var objectStr = JSON.parse(str);
var objectOutput = function(obj, counter) {
for (var i in obj) {
console.log(Array(counter + 1).join("-") + " " + i);
if (obj.hasOwnProperty(i)) {
if (obj[i] != null) {
objectOutput(obj[i], counter + 1);
}
}
}
};
objectOutput(objectStr, 0);
I am proxying the function console.log to add some information to my logs and I am as well checking whether the information being logged is an object. I do this to avoid getting a log entry of the sort
2016-12-17 (22:12:51) > [object Object]
Code works fine when passing arguments that are not objects. For example, the command
console.log("hello","world");
prints
2016-12-17 (22:23:53) > hello
2016-12-17 (22:23:53) > world
But if I pass an object as well, the code will fail to insert a new line after the object. For example, the command
console.log("hello",{world:true,hello:{amount:1,text:"hello"}},"world");
prints
2016-12-17 (22:27:32) > hello
2016-12-17 (22:27:32) > { world: true, hello: { amount: 1, text: hello } } 2016-12-17 (22:27:33) > world
(note the missing line break after displaying the object).
Code
JQuery 3.1.1
main.js:
(function (proxied) {
function displayArg(argument){
var result= "";
if(typeof argument == "object") {
result += "{ ";
for (i in argument) {
result += i + ": ";
result += (displayArg(argument[i]));
result += ", "
}
result = result.substring(0,result.length - 2);
result += " }";
return result;
} else {
return argument;
}
}
console.log = function () {
var result = [];
for (i in arguments) {
var d = new Date();
result[i] = d.getFullYear() + "-" + (d.getMonth() + 1) + "-" + d.getDate() +
" (" + d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() + ") > ";
result[i] += displayArg(arguments[i]);
result[i] += "\n";
}
return proxied.apply(this, result);
}
})(console.log);
I'm not fully understanding objective but what about something along the lines of the following oversimplified override:
var oldLog = console.log;
console.log= function(){
var d= new Date(),
dateString = // process string
.....
for(var i = 0; i<arguments.length; i++){
oldLog(dateString, arguments[i]);
}
}
TL;DR change the iterator variables so they don't share name, or add a "var" to the loop definition to make sure they don't escape your desired scope.
It turns out that the for loops from (my own) console.log and displayArg were "sharing" the value of the iterator i. This is because by not declaring the iterator variable, the scope was broader than what I needed. To clarify, look at this example:
console.log({isThis:"real life"},"hello","world")
The code from console.log will add a date to the beginning of result[0] and then call displayArg(arguments[0]), arguments[0] being {isThis:"real life"}. That function, will iterate over the objects properties, thus i will be assigned the value isThis. After the function returns, the value of i will not go back to 0. Instead, i will be isThis and as a consequence, the line
result[i] += "\n";
translates to
result[isThis] += "\n"
instead of
result[0] += "\n"
Probably the most sensible solution was to add a var in the for declaration of the iterators. The following code works as expected:
(function (proxied) {
function displayArg(argument){
var result= "";
if(typeof argument == "object") {
result += "{ ";
for (var i in argument) {
result += i + ": ";
result += (displayArg(argument[i]));
result += ", "
}
result = result.substring(0,result.length - 2);
result += " }";
return result;
} else {
return argument;
}
}
console.log = function () {
var result = [];
for (var i in arguments) {
var d = new Date();
result[i] = d.getFullYear() + "-" + (d.getMonth() + 1) + "-" + d.getDate() +
" (" + d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() + ") > ";
result[i] += displayArg(arguments[i]);
result[i] += "\n";
}
return proxied.apply(this, result);
}
})(console.log);
I created minor encrypt method to convert a small string based on distance between characters, but can't for the life of me figure out how to reverse it without knowing the distance between each character from the initial conversion. See image for example how it works imgur.com/Ine4sBo.png
I've already made the encrypt method here (Javascript):
var all = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.#-?").split('');
var position;
//var oKey = "P";
function encrypt() // Encrypt Fixed
{
var sEncode = ("HI-MOM").split('');
var oKey = "P";
for (var i = 0; i < sEncode.length; i++) {
if (all.indexOf(oKey) < all.indexOf(sEncode[i])) {
position = all.indexOf(sEncode[i]) - all.indexOf(oKey);
output.value += "oKey: " + oKey + " distance to sEncode[" + i + "]: " + sEncode[i] + " Count: " + position + " Final Char: " + all[position-1] + "\n";
oKey = sEncode[i];
}
else {
position = all.length - all.indexOf(oKey) + all.indexOf(sEncode[i]);
output.value += "oKey: " + oKey + " distance to sEncode[" + i + "]: " + sEncode[i] + " Count: " + position + " Final Char: " + all[position-1] + "\n";
oKey = sEncode[i];
}
}
}
However, it's the decrypt() method that's killing me.
From what I can tell, your encrypt function can be reduced to this:
var all = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.#-?").split('');
function encrypt(str)
{
var sEncode = str.split('');
var result = '';
var oKey = "P";
for(var i = 0; i < sEncode.length; i++)
{
result += all[(all.indexOf(sEncode[i]) - all.indexOf(oKey) + all.length - 1) % all.length];
oKey = sEncode[i];
}
return result;
}
(I got rid of the if clause by adding all.length either way, and removing it again with the remainder operator if necessary.)
From there, all you need to do is flip the operands (- all.indexOf(oKey) - 1 becomes + all.indexOf(oKey) + 1 (and since we have no more subtractions, adding all.length is no longer necessary)) and reverse the order (so oKey gets assigned the transformed value instead of the original one):
var all = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.#-?").split('');
function decrypt(str)
{
var sEncode = str.split('');
var result = '';
var oKey = "P";
for(var i = 0; i < sEncode.length; i++)
{
oKey = all[(all.indexOf(sEncode[i]) + all.indexOf(oKey) + 1) % all.length];
result += oKey;
}
return result;
}
I am having a problem with "\n" creating a line even when it is told not to when copying. The fix is probably something simple that I am just not seeing for some reason. I would appreciate any input or coaching on this problem.
(Please only give me Javascript answers as I am not interested in jquery or other methods)
<script type="text/javascript">
if (pullDownResponseE == "")
{
}
else {
var pullDownValuesE = document.getElementById("taskOne");
var pullDownResponseE = pullDownValuesE.options[pullDownValuesE.selectedIndex].value;
stuffToCopy = stuffToCopy + "\n" + pullDownResponseE;
}
if (pullDownResponseF == "")
{
}
else{
var pullDownValuesF = document.getElementById("taskTwo");
var pullDownResponseF = pullDownValuesF.options[pullDownValuesF.selectedIndex].value;
stuffToCopy = stuffToCopy + "\n" + pullDownResponseF;
}
</script>
As you can see, pullDownResponseF and pullDownReponseE should do nothing if my dropdown value equals "" and this portion works for the most part, it doesn't execute any of the else code EXCEPT for the new line "\n" part.
Can anyone explain what is going wrong here?
EDIT: Having more code might help here. I'll only include the essential portions since it is so long.
<script type="text/javascript">
function copyNotesTemplate()
{
var stuffToCopy = document.getElementById('myForm').value;
if(stuffToCopy.length > 1)
{
var stuffToCopy = "PT meets criteria" + "\n" + document.getElementById('myForm').value;
}
if(document.getElementById('noPtCriteria').checked)
{
var stuffToCopy = document.getElementById('noPtCriteria').value;
}
if (pullDownResponsee == "")
{
}
else {
var pullDownValuese = document.getElementById("taskOne");
var pullDownResponsee = pullDownValuese.options[pullDownValuese.selectedIndex].value;
stuffToCopy = stuffToCopy + "\n" + pullDownResponsee;
}
if (pullDownResponsef == "")
{
}
else{
var pullDownValuesf = document.getElementById("taskTwo");
var pullDownResponsef = pullDownValuesf.options[pullDownValuesf.selectedIndex].value;
stuffToCopy = stuffToCopy + "\n" + pullDownResponsef;
}
if (pullDownResponseg == "")
{
}
else{
var pullDownValuesg = document.getElementById("taskThree");
var pullDownResponseg = pullDownValuesg.options[pullDownValuesg.selectedIndex].value;
stuffToCopy = stuffToCopy + "\n" + pullDownResponseg;
}
var tempValues = document.getElementById('whatUpdate').value
if(tempValues.length > 1)
{
var stuffToCopy = stuffToCopy + "Updated" + " " + document.getElementById('whatUpdate').value + " ";
}
else{
}
var tempValuess = document.getElementById('whatInfo').value
if(tempValuess.length > 1)
{
var stuffToCopy = stuffToCopy + "per" + " " + document.getElementById('whatInfo').value + "\n";
}
else{
}
var tempValue = document.getElementById('whatDSCRP').value
if(tempValue.length > 1)
{
var stuffToCopy = stuffToCopy + document.getElementById('whatDSCRP').value + " " + "dscrp on Collection tube and trf was resolved using" + " ";
}
else{
}
var tempValue = document.getElementById('resolveIT').value
if(tempValue.length > 1)
{
var stuffToCopy = stuffToCopy + document.getElementById('resolveIT').value + " ";
}
else{
}
var tempValue = document.getElementById('tubeCorrect').value
if(tempValue.length > 1)
{
var stuffToCopy = stuffToCopy + "trf was" + " " + document.getElementById('tubeCorrect').value;
}
else{
}
if(stuffToCopy.length > 1)
{
var stuffToCopy = stuffToCopy + "\n" + document.getElementById('moreNotes').value;
}
else{
}
if (pullDownResponsesu == "")
{
}
else{
var pullDownValuesu = document.getElementById("mod33Apply");
var pullDownResponsesu = pullDownValuesu.options[pullDownValuesu.selectedIndex].value;
stuffToCopy = stuffToCopy + "\n" + pullDownResponsesu;
}
if (pullDownResponsesb == "")
{
}
else{
var pullDownValuesb = document.getElementById("resultICR");
var pullDownResponsesb = pullDownValuesb.options[pullDownValuesb.selectedIndex].value;
stuffToCopy = stuffToCopy + "\n" + pullDownResponsesb + "," + " ";
}
if (pullDownResponsesc == "")
{
}
else{
var pullDownValuesc = document.getElementById("moneyNCIS");
var pullDownResponsesc = pullDownValuesc.options[pullDownValuesc.selectedIndex].value;
stuffToCopy = stuffToCopy + pullDownResponsesc + " ";
}
if (pullDownResponsesd == "")
{
}
else{
var pullDownValuesd = document.getElementById("resultMMT");
var pullDownResponsesd = pullDownValuesd.options[pullDownValuesd.selectedIndex].value;
stuffToCopy = stuffToCopy + pullDownResponsesd;
}
if(stuffToCopy.length > 1)
{
var stuffToCopy = stuffToCopy + " " + "Reason:" + " " + document.getElementById('whyNotEligible').value;
}
else{
}
if (pullDownResponsesa == "")
{
}
else{
var pullDownValuesa = document.getElementById("testReleased");
var pullDownResponsesa = pullDownValuesa.options[pullDownValuesa.selectedIndex].value;
stuffToCopy = stuffToCopy + "\n" + pullDownResponsesa;
}
window.clipboardData.setData('text', stuffToCopy);
}
</script>
If somebody skips filling out a note field or skips a dropdown in this example then it will not execute the code like I intended but it does create a new line when copied like this:
taskOne selected
(extra line here since task two wasn't selected)
taskThree selected
I would like there not to be an extra line between Task one and three if task two is skipped. Like this:
taskOne selected
taskThree selected
Note: I know that having else {} is pointless but it helps me visually.
I created snips of exactly what it looks like when copy/pasted from my tool that you can view here if you would like:
Example 1: http://imgur.com/wGO5vnT
Example 2: http://imgur.com/UX1tG5S
Here is an example of my html as well:
<html lang="en">
What tasks are needed for the case?
<br />
<select class="style3" id="taskOne">
<option value=""></option>
<option value="ABN needed">ABN needed</option>
<option value="Auth needed">Auth needed</option>
</select>
</html>
No, it doesn't add a new line, see:
stuffToCopy = "";
controlGroup = "a\nb";
pullDownResponseE = "";
if (pullDownResponseE == "")
{
}
else {
var pullDownValuesE = "taskOne";
var pullDownResponseE = "value";
stuffToCopy = stuffToCopy + "\n" + pullDownResponseE;
}
alert("stuffToCopy:"+stuffToCopy+";(no new-line here)\ncontrolGroup:"+controlGroup);
My guess is that your html is printed in such away that the values you get from the inputs contain an extra new-line at the end. Try changing your html to be 1 line, without new-lines, and test again.
Instead of:
<option value="a
">b
</option>
try:
<option value="a">b</option>
Alright so I fixed it, should have used the almighty document.getElementById instead of attempting to use pullDownReponse for my if statements..
I simply changed the if statements like this:
if (pullDownResponseg == "")
{
}
To this:
if (document.getElementById("taskThree").value == "")
{
}
Thanks for the help from the sincere. (and ridiculous non-answers from the others)