Trying to add and remove items from an array - javascript

The script works by asking user for add or remove an item in the array. Then asks to continue this loop. The problem here is that my script doesn't seem to match my user's input (removeItem) to the item in the list (myList[i]). I'm at a lost as to why this is failing to match.
// new method for removing specific items from a list
Array.prototype.remove = function(from,to) {
var rest = this.slice((to || from) + 1 || this.length);
this.length = from < 0 ? this.length + from : from;
return this.push.apply(this, rest);
};
printList = function() {
var listLength = myList.length;
for (i = 0; i < listLength; i++) {
document.write(i + ":");
document.write(myList[i] + "<br/>");
};
document.write("<br/><br/>");
};
// initial list
var myList = new Array ();
if (myList.length === 0) {
document.write("I have " + myList.length + " item in my list. It is: <br/>");
}
else {
document.write("I have " + myList.length + " items in my list. They are: <br/>");
}
printList();
var continueAdding = "yes";
var askToContinue = "";
while (continueAdding === "yes") {
// loop
var askUser = prompt("What do you want to [A]dd or [R]emove an item to your inventory?").toUpperCase();
switch (askUser) {
case "A": { // add an user specified item to the list
var addItem = prompt("Add something to the list");
myList.push(addItem);
printList();
break;
}
case "R": { // remove an user specified item from the list
var removeItem = prompt("what do you want to remove?");
var listLength = myList.length;
for (i = 0; i < listLength; i++) {
if (removeItem === myList[i]) {
document.write("I found your " + removeItem + " and removed it.<br/>");
myList.remove(i);
}
else {
document.write(removeItem + " does not exist in this list.<br/>");
break;
}
if (myList.length === 0) {
myList[0] = "Nada";
}
};
printList();
break;
}
default: {
document.write("That is not a proper choice.");
}
};
askToContinue = prompt("Do you wish to continue? [Y]es or [N]o?").toUpperCase(); // ask to continue
if (askToContinue === "Y") {
continueAdding = "yes";
}
else {
continueAdding = "no";
}
}

Your loop never allows it to loop through all the items, because it breaks on the first iteration if the item doesn't match.
The break statement should be in the if block, not in the else block - use this instead:
for (i = 0; i < listLength; i++) {
if (removeItem === myList[i]) {
document.write("I found your " + removeItem + " and removed it.<br/>");
myList.remove(i);
break;
}
else {
document.write(removeItem + " does not exist in this list.<br/>");
}
};
if (myList.length === 0) {
myList[0] = "Nada";
}
Also, note that it's looking for an exact match, case sensitive, same punctuation, and everything. If you want it to be a little more lenient you'll need to modify the script to convert both strings to lowercase and strip punctuation before comparing them.
Edit: Just noticed something else -- testing for an empty list needs to be done outside the loop. I updated the above code to reflect this.

Related

JavaScript - Nested FOR loop executing twice

I have a nested FOR loop that iterates over an object, and updating variables or attributes based on conditions. The last 'IF' on this loop formats a date and updates the field accordingly. For some reason the final line causes the loop to iterate twice, therefore updating the 'formattedDate' variable twice (in the object, there is only one single element with the 'childTag' = 'date'. Any help is appreciated!
for (let i = 0; i < submitFormData.tabs.length; i++) {
for (let j = 0; j < submitFormData.tabs[i].elements.length; j++) {
if (submitFormData.tabs[i].elements[j].childTag == "project_name") {
projectName = submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "location_store") {
locationStore = ' #' + submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "location_street") {
locationStreet = submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "location_city") {
locationCity = submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "location_state") {
locationState = submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "location_zip") {
locationZip = submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "date") {
if (submitFormData.tabs[i].elements[j].value != "") {
console.log(submitFormData)
date = (submitFormData.tabs[i].elements[j].value.substring(0, 10));
formattedDate = (date.substring(5, 11) + '-' + date.substring(0, 4));
console.log(formattedDate, 'formatted date')
submitFormData.tabs[i].elements[j].value = formattedDate;
}
}
}
}
Sample of Object
I see that in the loop you manipulate the list which you iterate over.
submitFormData.tabs[i].elements
It would be better to make a copy of it and iterate over it.
const newSubmitFormData = [...submitFormData.tabs[i].elements]
for (let j = 0; j < newSubmitFormData .length; j++) { /* your code */ }

Javascript loop within a loop-only executes first time

Please see my js validation function below.
function validate_submit(PassForm) {
var bGo = false;
var rankcount = document.getElementById('rankCount').value;
var j = 0;
var iRankcount0 = document.getElementById('indRankcount0').value;
var iRankcount1 = document.getElementById('indRankcount1').value;
var iRankcount2 = document.getElementById('indRankcount2').value;
var ijs = 0;
var itemp = ijs;
for (i = 0; i < rankcount; i++) {
alert("begin i = " + i);
if (i == 0) {
indRankcount = iRankcount0;
}
else if (i == 1) {
alert('indRankcount: ' + indRankcount);
indRankcount = iRankcount1;
alert('iRankcount1: ' + iRankcount1);
alert('indRankcount: ' + indRankcount);
}
else if (i == 2) {
indRankcount = iRankcount2;
}
alert('before sec loop indRank: ' + indRankcount);
alert('before sec loop itemp: ' + itemp);
for (k = itemp; k < indRankcount; k++) {
alert('in check bGo');
if (document.getElementById("selectedScore" + i + k).checked) {
bGo = true;
j++;
} //if
} //for indRankcount - k loop
if (bGo) {
if (i == 0) {
par = (Math.ceil(indRankcount / 4));
}
else if (i == 1) {
par = (Math.ceil((iRankcount1 - iRankcount0) / 4));
alert('1: ' + par);
}
else if (i == 2) {
par = (Math.ceil((indRankcount2 - iRankcount1) / 4));
}
if (j == par) {
j = 0;
bGo = false;
itemp = indRankcount;
alert("itemp = " + itemp);
continue;
}
else {
alert('25% criteria not met.');
return false;
}
}
else { //else to check bGo
alert('Atleast one box need to be selected.');
return false;
}
j = 0;
bGo = false;
itemp = indRankcount;
alert("loop ends: i =" + i);
} //for rankcount - i loop
res = window.confirm('Are you sure you want to proceed with the selection?');
if (res) {
return true;
}
else {
return false;
}
} //end of validate
Problem is when i=0, it executes fine. But when i=1, second loop (K) doesn't execute(we switched the variable to constant- it works for either itemp or indRankcount.Just one number did it.) It totally skips. Help please! Thank you!
After the inner loop (which uses "k"), there is a "itemp = indRankcount;" line. I guess this cause the issue.
On the first run the "itemp" is 0 so the inner loop step in, but on the second run this value more or equal with the "indRankcount", because you call the code before.
What values are stored in "iRankcount0", "iRankcount1" and "iRankcount2"?
Try to print the "itemp" and "indRankcount" values before the 2. loop.
Updated, try this before the k loop, it will show why the k not starts on the 2. execution.
Console.log(i + "loop:: " + itemp + " val (k first val), " + " indRankcount " + val (k end val));

Javascript array push issue or loop issue

When I'm running my code I'm going into 'do' loop, then I'm entering input 'new' and then trying to add new array, but for some reason my code starting looping in if(answ == "new"). What am I doing wrong?
Here is my code:
var answ;
var arr = [];
do{
answ = prompt("What would like to do?");
if(answ == "new"){
var add = prompt("Add new todo: ");
add = arr.push(answ);
}
else if(answ == "list"){
for(var i=0; i<arr.length; ++i){
answ = answ + arr[i] + '<br>';
}
}
else if(answ == "delete"){
var choose = prompt("Which one (index)?");
delete arr[choose];
}
}while(answ !== "quit")
Don't run in browser in current form (never ending loop)
See if this helps you Mark.
there were some errors with you logic and storing values and also you were not showing the values, if what I suggest is right.
var answ;
var arr = [];
do {
answ = prompt("What would like to do?");
if (answ == "new") {
var add = prompt("Add new todo: ");
arr.push(add);
} else if (answ == "list") {
var output = '';
for (var i = 0; i < arr.length; ++i) {
output += arr[i] + '\r\n';
}
alert('listing:' + '\r\n' + output );
} else if (answ == "delete") {
var choose = prompt("Which one (index)?");
arr.splice(choose,1);
} else {
if(answ !== "quit")
alert('option invalid!');
}
} while (answ !== "quit")

How to assign 2 or + variables

sorry I'm french and I speak just few word in english.
I have a question maybe stupid :
Original code :var test = {
commandChar : "!",
};
for (i = 0; i < commands.length; i++) {
if (commands[i].hasOwnProperty('alt')) {
for (j = 0; j < commands[i].alt.length; j++) {
if ((index = text.toLowerCase().search(new RegExp("^\\" + test.commandChar + commands[i].alt[j].toLowerCase() + "\\b"))) >= 0) {
break;
}
}
}
if (index < 0) {
index = text.toLowerCase().search("^\\" + "[" + test.commandChar + ",##]" + commands[i].name.toLowerCase() + "\\b");
}
if (index > -1) {
var command = text.slice(index).split(" ");
if (!(commands[i].op || commands[i].elevated) || host || mod || authorised) {
if (!(commands[i].mod) || host || mod) {
commands[i].command(command, user);
}
}
else {
//sendChat("You have to be authorised to use " + commands[i].name + ".");
}
break;
}
}
This is an little bot, example.
If commandChar : "!". !help work but /help dont work.
I want just use this commandChar with many symbole
like
commandChar : "!", "/";
for use !help and /help
I think it should or array or regexpr
Sorry if I did not express myself properly it's complicated, thanks
There's many ways to do it but here's a quick one:
function isValidCommandChar(str) {
return "!/.".indexOf(str.charAt(0)) > -1;
}
isValidCommandChar("!help"); // true
isValidCommandChar("#help"); // false
isValidCommandChar("/help"); // true
isValidCommandChar(".help"); // true

Ensuring that an entered name doesn’t end with a space

I am trying to get it so that if I type in a name that ends with a space, the textfield will go red. Most of the code works its just one method does not seem to be working.
The issue must be somewhere in the last index part?
var NamePass = true;
function ValidateName() {
var BlankPass = true;
var GreaterThan6Pass = true;
var FirstBlankPass = true;
var BlankMiddleName = true;
if (document.getElementById('Name').value == "") {
BlankPass = false;
}
var Size = document.getElementById('Name').value.length;
console.log("Size = " + Size);
if (Size < 7) {
GreaterThan6Pass = false;
}
if (document.getElementById('Name').value.substring(0, 1) == " ") {
FirstBlankPass = false;
}
var LastIndex = document.getElementById('Name').value.lastIndexOf();
if (document.getElementById('Name').value.substring((LastIndex - 1), 1) == " ") {
FirstBlankPass = false;
}
string = document.getElementById('Name').value;
chars = string.split(' ');
if (chars.length > 1) {} else
BlankMiddleName = false;
if (BlankPass == false || GreaterThan6Pass == false || FirstBlankPass == false || BlankMiddleName == false) {
console.log("BlankPass = " + BlankPass);
console.log("GreaterThan6Pass = " + GreaterThan6Pass);
console.log("FirstBlankPass = " + FirstBlankPass);
console.log("BlankMiddleName = " + BlankMiddleName);
NamePass = false;
document.getElementById('Name').style.background = "red";
} else {
document.getElementById('Name').style.background = "white";
}
}
http://jsfiddle.net/UTtxA/10/
lastIndexOf gets the last index of a character, not the last index in a string. I think you meant to use length instead:
var lastIndex = document.getElementById('Name').value.length;
Another problem with that, though, is that substring takes a start and end index, not a start index and a substring length. You could use substr instead, but charAt is easier:
if (document.getElementById('Name').value.charAt(lastIndex - 1) == " ") {
FirstBlankPass = false;
}
Now, for some general code improvement. Instead of starting with all your variables at true and conditionally setting them to false, just set them to the condition:
var NamePass = true;
function ValidateName() {
var value = document.getElementById('Name').value;
var BlankPass = value == "";
var GreaterThan6Pass = value.length > 6;
var FirstBlankPass = value.charAt(0) == " ";
var LastBlankPass = value.charAt(value.length - 1) == " ";
var BlankMiddleName = value.split(" ").length <= 1;
if (BlankPass || GreaterThan6Pass || FirstBlankPass || LastBlankPass || BlankMiddleName) {
console.log("BlankPass = " + BlankPass);
console.log("GreaterThan6Pass = " + GreaterThan6Pass);
console.log("FirstBlankPass = " + FirstBlankPass);
console.log("BlankMiddleName = " + BlankMiddleName);
NamePass = false;
document.getElementById('Name').style.background = "red";
} else {
document.getElementById('Name').style.background = "white";
}
}
A couple more points of note:
It’s probably a good idea to use camelCase variable names instead of PascalCase ones, the latter usually being reserved for constructors
blah == false should really be written as !blah
An empty if followed by an else can also be replaced with if (!someCondition)
That function looks like it should return true or false, not set the global variable NamePass
Penultimately, you can sum this all up in one regular expression, but if you intend to provide more specific error messages to the user based on what’s actually wrong, then I wouldn’t do that.
function validateName() {
return /^(?=.{6})(\S+(\s|$)){2,}$/.test(document.getElementById('name').value);
}
And finally — please keep in mind that not everyone has a middle name, or even a name longer than 6 characters, as #poke points out.

Categories