replacing variables of an array in a loop - javascript

I'm trying to make some sort of cryptographer, and I need to replace for ex. every "a" with "b" when the user asks for it.
if (DoYouWannaCrypt == 1) {
binput.forEach(function(v, i) {
if(v === "a") {
input[i] = "$"
}
})
};
This works fine, however I want to add another condition that this should only be done for all 5th values of another array.
if (Val is 5th) {
if (DoYouWannaCrypt == 1){
binput.forEach(function(v, i) {
if(v === "a") {
input[i] = "$"
}
})
}
};
I think you can see where I'm stuck at. I need it to work for all 5th values not just the first one.

Thats what map is for:
var crypted=binput.map((l,i)=>(i+1)%5?l:({"a":"$"}[l]||l));
http://jsbin.com/zepewituro/edit?console
Check if index (starting from 0, thats why +1 ) modulo 5 is not 0,then take the letter l, if its 0 ( then we are at the 5*n th position), then we try to replace our letter with another one, if it isnt possible fallback to the letter (||l).

Since your code appears irrelevant to your problem, let me store it safely in a function first:
function something(binput, input, DoYouWannaCrypt) {
if (DoYouWannaCrypt == 1)
binput.forEach(function(v, i) {if (v === "a") input[i] = "$"});
}
If you want to do this operation only for the first element of anotherArray:
for (let Val in anotherArray)
if (!Val) something(binput, input, DoYouWannaCrypt);
If you want to do it for every element of anotherArray:
for (let Val in anotherArray)
something(binput, input, DoYouWannaCrypt);
If you want to do it for every fifth element of anotherArray:
for (let Val in anotherArray)
if (!(Val%5)) something(binput, input, DoYouWannaCrypt);

Related

How to remove the first index of an array based on input value?

I apologize in advance if i'm not conveying things properly.
I'm trying to take an array, split the strings into characters, and remove the first index if it matches my input value, and continue linearly.
I'm a little lost on how I should be thinking about solving this problem.
So far I have gotten to here,
showCurrentValue = (event) => {
const value = event.target.value;
document.getElementById("textV").innerText = value;
let arrIndex = newArr[0].split('');
for (let i = 0; i < arrIndex.length; i++) {
if (value === arrIndex[0]) {
console.log("Match");
arrIndex.shift()
} else {
console.log("Err")
}
}
}
With or without the loop it still behaves the same, it DOES remove the first index, but fails to continue, and logs "Err" for all the rest of the characters in the string. It won't match the next character. In my head i'm thinking if I just target the 0 index, and the array will update as each character is removed(?).
Hope someone can shine some light on this, Thanks!!
Basically, i'm trying to build one of those Typing speed test applications.
So I have my array of randomized words rendered to the DOM with an input field below it.
If, the input value matches the first character, I want to manipulate it based on if true or false. Change it's color, remove it from the DOM, etc.
So, my issue currently is getting the 2nd character of my input to compare to the next current character index.
Maybe my whole approach is wrong(?)
The first time you hit a situation where your value !== arrIndex[0], you keep viewing the same element (arrIndex[0]) and not iterating to the next element.
#wlh's comment is pretty close to the solution I think you're looking for:
const filtered = arrIndex.filter(char => char !== value);
filtered will then have all the elements of arrIndex but remove any and all elements that matched value.
This is just one possible solution. You continue moving thru arrIndex with out changing its length, checking each case, and adding the cases which don't match your value to a new array. Once you have finished moving thru the arrIndex then you assign arrIndex to the updatedIndex;
showCurrentValue = (event) => {
const value = event.target.value;
let updatedIndex = [];
const arrIndex = newArr[0].split('');
for (let i = 0; i < arrIndex.length; i++) {
if (value !== arrIndex[i]) {
console.log("Err");
updatedIndex.push(arrIndex[i]);
} else {
console.log("Match")
}
}
arrIndex = updatedIndex.join('');
}
Another solution could be
showCurrentValue = (event) => {
const value = event.target.value;
let arrIndex = newArr[0].split('').filter((char) => char !== value);
return arrIndex;
}
.filter will return a new array - it will loop thru each char and return ones which don't match your value

Code will loop itself three time and runs "If" statement twice and "Else" statement once

i do not know why but this bit of code repeats itself 3 times when adding "questionwords" in the message, specifically it will run the else statement one and the main if statement twice.
bot.on('message', function(message) {
const words = message.content.split(' ');
if (words.includes('sans')) {
var questionwords = ['can', 'is', 'was', ];
for (i in questionwords)
if (!words.includes(questionwords[i])) {
if (message.author.bot) return;
var chance = Math.floor(Math.random() * 2);
if (chance == 0) {
message.channel.send('<:annoying_sans:520355361425981440>');
}
if (chance == 1) {
message.channel.send('<:sans:519723756403425294>');
}
} else {
var chance = Math.floor(Math.random() * 3);
if (chance == 0) {
message.channel.send('Maybe.');
}
if (chance == 1) {
message.channel.send('Yes.');
}
if (chance == 2) {
message.channel.send('No.');
}
}
}
});
To me it looks like you want to know if the words in the questionwords array were in the message. You already know how to check a single word using Array.includes(), but multiple words are more complicated.
If you just want to know if any word in the words array matches any word in the questionwords array, you can use Array.some():
var wereAnyFound = words.some(word => questionwords.indexOf(word) > -1);
// true or false
Maybe you want to make sure they are ALL in there, use Array.every():
var wereAllPresent = words.every(word => questionwords.indexOf(word) > -1);
// true or false
Maybe you want to know how many, or you want to get the matches (Array.filter()):
var matches = words.filter(word => questionwords.indexOf(word) > -1);
// an array of matches
var howMany = matches.length;
// number
Like James said in the comments, because there are three words in the questionwords array, your for loop will run three times. It will then reply once for each word.
However, if you remove the for loop and change
if (!words.includes(questionwords[i]))
to
if (!words.includes("can" || "is" || "was"))
you'll get the same result without the bot repeating itself, as it will search for "can" or "is" or "was" instead of "can" and then "is" and then "was".

indexOf ignores second character in array

I'm just studying JS and I need to write a program that checkes if the string in the first element of the array contains all of the letters of the string in the second element of the array.
I've made a code like this:
function mutation(arr) {mutation: {
var lowerCaseStringOne = arr[0].toLowerCase();
var lowerCaseStringTwo = arr[1].toLowerCase();
if (lowerCaseStringOne === lowerCaseStringTwo) {
console.log(true);
break mutation;
}
var newArray = [];
for (var i = 0; i < lowerCaseStringTwo.length; i++){
console.log(lowerCaseStringTwo[i]);
if (lowerCaseStringTwo.indexOf(lowerCaseStringOne[i]) > 0) {
newArray.push(lowerCaseStringTwo[i]);
console.log('---');
}
}
var result = newArray.join("");
if (result === lowerCaseStringTwo) {
console.log(true);
} else {
console.log(false);
}
}
}
mutation(["Mary", "Aarmy"]);
I think it's very complicated, but I can't solve the problem - the "indexOf" function seems to ignore a second character in my loop - loggs it in the console but doesn't pushes into an array. I thought it could happen because first and second letters are similar, but it's not. No matter what letter, it just ignores it.
indexOf() will return 0 for the letter "a" in your example as the first instance is at position 0 in the array.
You should be using ">= 0"

Google Script - Consolidated operator syntax not working in IF statement

Conext
I would like my onEdit(e) function below to add or remove rows from a spreadsheet based on the new and old values of a cell. This requires the OR (||) operator in my IF statement to check the values. Below is my first attempt which sort of worked but led to some odd behavior such as rows appearing then disappearing (the second IF statement) after a single edit, two rows appearing whenever I hit the "delete" key, etc:
function onEdit(e) {
var range = e.range;
var newValue = e.value;
var oldValue = e.oldValue;
var targetRow = range.getRow();
//insert 2 rows if edited cell value = "a" or "b"
if (newValue === "a" || "b") {
sheet.insertRowsAfter(targetRow, 2);
}
//delete 2 rows if former cell value was "a" or "b"
if (oldValue === "a" || "b") {
sheet.deleteRows(targetRow + 1, 2);
}
}
Applications Currently Used
Google Sheets
Google Apps Script
What I've Tried So Far
When I changed my IF statements to restate the variable after each OR operator, the desired result was produced cleanly:
if (newValue === "a" || newValue === "b") {
sheet.insertRowsAfter(targetRow, 2);
}
if (oldValue === "a" || oldValue === "b") {
sheet.deleteRows(targetRow + 1, 2);
}
Question
Is there a consolidated form of writing these statements that will continue to produce the desired result? As I continue writing this function, these IF statements are likely to become more complex and the same variable will need to be checked using OR and AND operators. It would be much easier to only state the variable name once for each operator.
To recap:
I would like to be able to write the consolidated format of the code as shown in the first code snippet:
if (newValue === "a" || "b") { //etc...
However, it only works properly when written in the longer version:
if (newValue === "a" || newValue == "b") { //etc...
Thank you!
You could use the switch statement to consolidate.
switch (newValue) {
case "a":
case "b":
sheet.insertRowsAfter(targetRow, 2);
break;
default:
}
You could add more cases there to "OR" the overall condition if required.

remove items from object if value is empty

So I'm taking a form and using serializeArray() to get all the forms data. There are 10 text inputs. What I am trying to do is skip the forms that return a empty result or forms that have "" as value. Here is what I came up with and it returns the index of the forms with "" or empty results correctly.
$("#" + forms).on("submit", function(event) {
var allData = $(this).serializeArray();
event.preventDefault();
for (var key in allData) {
if (allData[key].value === "") {
allData.splice(key, 1);
}
}
});
But when I add allData.splice(key, 1); it doesn't remove all the values with "" as a result. I basically want to remove any input that isn't going to have a value.
Also the structure of the objec is as follows.
[0]
name: "emailone",
value "some#email.com"
[1]
name: "passwordone",
value: "123asd"
[2]
name: "emailtwo",
value "another#email.com"
[3]
name: "passwordtwo",
value: "asd123"
[4]
name: "emailthree",
value ""
[5]
name: "passwordthree",
value: ""
That happens because you are altering the array while traversing it...
When you key is 4 and the value is '' you remove that element (succesfully) but when you splice the array it becomes a smaller one.. so the element at position 5 is now at 4. Your key variable is increased to 5 but now there is no element 5 in your array..
You need to traverse it backwards
$("#" + forms).on("submit", function(event) {
var allData = $(this).serializeArray();
event.preventDefault();
for (var key = allData.length-1; key >= 0 ; key--) {
if (allData[key].value === "") {
allData.splice(key, 1);
}
}
});
By splicing an array as you iterate over it, you can accidentally skip values - in this case, by removing a value at index four, you decrease the index of the following value by one. The loop than increments to five, and the value that started at the fifth index is skipped.
A few other answers have posted reasonable ways to work around this. If you're working with a newer version of JavaScript or with a library like jQuery or underscore, you could alternatively do this:
allData = allData.filter(function(e) {
return e.value !== "";
});
With jQuery, this can be written as
allData = $.grep(allData, function(e) {
return e.value !== "";
});
and in underscore:
allData = _.filter(allData, function(e) {
return e.value !== "";
});
var arrLength = allData.length, i, cleanArray = [], serializedArr;
for(i = 0; i < arrLength; i += 1{
if(allData[i] != ""){
cleanArray.push(allData[i]);
}
}
serializedArr = cleanArray.serializeArray();
You simply use delete to achieve your need,
for (var key in allData) {
if (allData[key].value === "") {
delete allData[key];
}
}
additionally you don't need explicitly get the value by this toallData[key].value, toallData[key] will simply return the value associated with the particular key.
DEMO
Updated:
for (var i=0; i < allData.length ; I++) {
if (allData[i].value === "") {
allData.splice(i, 1);
i--;
}
}
You should decrement the value of the index by one, every time you are removing an object from the array.

Categories

Resources