How to replace undefined value with a string - javascript

I tried to use this code:
if((data.memberData.workStreak || 0) >= 5){
won+=400;
embed.addField(message.language.get("WORK_CLAIMED_HEADINGS")[0], message.language.get("WORK_CLAIMED_SALARY", won))
.addField(message.language.get("WORK_CLAIMED_HEADINGS")[1], message.language.get("WORK_AWARD"));
data.memberData.workStreak = 0;
} else {
for(let i = 0; i < award.length; i++){
if (typeof i === 'undefined') {
return '<:b_:682865394637078531>';
}
if(data.memberData.workStreak > i){
let letter = Discord.Util.parseEmoji(award[i]).name.split("_")[1];
award[i] = ":regional_indicator_"+letter+":";
}
}
But it did absolutely nothing.
Any help?

You can simply use the OR operator and print string instead of undefined. In below statement if a is undefined then it will store empty string in a instead of undefined.
a = a || ''
Replace your line with below line:
let letter =Discord.Util.parseEmoji(award[i]).name;
OR
let letter =Discord.Util.parseEmoji(award[i]);
Please find working snippit below:
const a = undefined;
console.log(a);
console.log(a || '');

I don't know exactly, what this little code snippet is aimed to do.. But may this could help you?
let letter = Discord.Util.parseEmoji(award[i]).name.split("_")[1];
if (letter == undefined) {
return '<:b_:682865394637078531>';
}
if(data.memberData.workStreak > i){
award[i] = ":regional_indicator_"+letter+":";
}

Related

check the alphabetical order

I am a newbie who is trying hard to have a grip on javascript. please help me to consolidate my fundamentals.
input will be a string of letters.
following are the requirements.
function should return true if following conditions satisfy:
letters are in alphabetical order. (case insensitive)
only one letter is passed as input. example :
isAlphabet ('abc') === true
isAlphabet ('aBc') === true
isAlphabet ('a') === true
isAlphabet ('mnoprqst') === false
isAlphabet ('') === false
isAlphabet ('tt') === false
function isAlphabet(letters) {
const string = letters.toLowerCase();
for (let i = 0; i < string.length; i++) {
const diff = string.charCodeAt(i + 1) - string.charCodeAt(i);
if (diff === 1) {
continue;
} else if (string === '') {
return false;
} else if (string.length === 1) {
return true;
} else {
return false;
}
}
return true;
}
It's generally a better practice to start your function off with dealing with the edge-cases rather than putting them somewhere in the middle. That way, the function returns as soon as it can - and it's a lot easier to read than a waterfall of if..else statements.
function isAlphabet(letters) {
if ("" == letters) {
return false;
}
if (1 == letters.length) {
return true;
}
const string = letters.toLowerCase();
// carry on with your loop here.
}
You've got the right idea, but it can be simplified to just fail on a particular error condition, i.e when a smaller character follows a larger one:
function isAlphabet(letters) {
const string = letters.toLowerCase();
let lastChar;
for (let i = 0; i < string.length; i++) {
// Grab a character
let thisChar = string.charCodeAt(i);
// Check for the failure case, when a lower character follows a higher one
if (i && (thisChar < lastChar)) {
return false;
}
// Store this character to check the next one
lastChar = thisChar;
}
// If it got this far then input is valid
return true;
}
console.log(isAlphabet("abc"));
console.log(isAlphabet("aBc"));
console.log(isAlphabet("acb"));
You can use the simple way to achieve the same as below
function isAlphabet(inputString)
{
var sortedString = inputString.toLowerCase().split("").sort().join("");
return sortedString == inputString.toLowerCase();
}
console.log("abc = " + isAlphabet("abc"));
console.log("aBc = " + isAlphabet("aBc"));
console.log("acb = " + isAlphabet("acb"));
console.log("mnoprqst = " + isAlphabet("mnoprqst"));
Note: Mark the answer is resolves your problem.

Iteration through string and remove all instances of

My instructions were to iterate through a string and remove all instances of the letter "a". I thought that it would be easy to find examples, but I was unable to do so. Some would remove the letter without the iteration, but that is not what the instructions asked. If someone could please look at my code and assist me in my task I would greatly appreciate it! The "removeA" function will iterate through the string now, and only console logs the !== "a", but for the life of me I can't figure out how to save it to a new string. Thanks in advance.
removeA = function(stringWithA) {
if (stringWithA === null || typeof (stringWithA) !== "string" || stringWithA === "") { //Checking for is null AND is not array
return 'Please enter a valid string';
} else {
lowerWithA = stringWithA.toLowerCase();
for (var i = 0; i < lowerWithA.length; i++) {
if (lowerWithA.charAt(i) !== "a") {
console.log(lowerWithA.charAt(i));
}
}
}
}
You can store the letters into an Array.
var removeA = function(stringWithA) {
if (stringWithA === null || typeof(stringWithA) !== "string" || stringWithA === "") { //Checking for is null AND is not array
return 'Please enter a valid string';
} else {
var newString = [];
lowerWithA = stringWithA.toLowerCase();
for (var i = 0; i < lowerWithA.length; i++) {
if (lowerWithA.charAt(i) !== "a") {
newString.push(lowerWithA.charAt(i))
}
}
return newString.join('');
}
}
console.log(removeA("Eleazar"))
Or, just use a regex:
var removeA = function(stringWithA) {
if (stringWithA === null || typeof(stringWithA) !== "string" || stringWithA === "") { //Checking for is null AND is not array
return 'Please enter a valid string';
} else {
return stringWithA.replace(/a/gi, '')
}
}
console.log(removeA("EleaaaaazAreeeeaaaElAAAAAeaaaEleEvene"))
Why not build a new string with all the characters that are not a?
var newString = "";
for (var i = 0; i < lowerWithA.length; i++) {
var letter = lowerWithA.charAt(i);
if (letter !== "a") {
newString += letter;
}
}
console.log(newString);
If you wanted to expand this to be case-insensitive:
...
if (letter !== 'a' || letter !== 'A') { ... }
And simply don't call String.toLowerCase() on the original string.
I suppose there's already a function that you need, replace:
var stringWithA = 'A aaaa bbbcc!';
alert(stringWithA.replace(/[Aa]/g, ''));

Get function parameter length including default params

If you make use of the Function.length property, you get the total amount of arguments that function expects.
However, according to the documentation (as well as actually trying it out), it does not include Default parameters in the count.
This number excludes the rest parameter and only includes parameters before the first one with a default value
- Function.length
Is it possible for me to somehow get a count (from outside the function) which includes Default parameters as well?
Maybe you can parse it yourself, something like:
function getNumArguments(func) {
var s = func.toString();
var index1 = s.indexOf('(');
var index2 = s.indexOf(')');
return s.substr(index1 + 1, index2 - index1 - 1).split(',').length;
}
console.log(getNumArguments(function(param1, param3 = 'test', ...param2) {})); //3
Copying my answer over to here from a duplicate question:
Well, it's a bit of a mess but I believe this should cover most edge cases.
It works by converting the function to a string and counting the commas, but ignoring commas that are in strings, in function calls, or in objects/arrays. I can't think of any scenarios where this won't return the proper amount, but I'm sure there is one, so this is in no way foolproof, but should work in most cases.
UPDATE: It's been pointed out to me that this won't work for cases such as getNumArgs(a => {}) or getNumArgs(function(a){}.bind(null)), so be aware of that if you try to use this.
function getNumArgs(func) {
var funcStr = func.toString();
var commaCount = 0;
var bracketCount = 0;
var lastParen = 0;
var inStrSingle = false;
var inStrDouble = false;
for (var i = 0; i < funcStr.length; i++) {
if (['(', '[', '{'].includes(funcStr[i]) && !inStrSingle && !inStrDouble) {
bracketCount++;
lastParen = i;
} else if ([')', ']', '}'].includes(funcStr[i]) && !inStrSingle && !inStrDouble) {
bracketCount--;
if (bracketCount < 1) {
break;
}
} else if (funcStr[i] === "'" && !inStrDouble && funcStr[i - 1] !== '\\') {
inStrSingle = !inStrSingle;
} else if (funcStr[i] === '"' && !inStrSingle && funcStr[i - 1] !== '\\') {
inStrDouble = !inStrDouble;
} else if (funcStr[i] === ',' && bracketCount === 1 && !inStrSingle && !inStrDouble) {
commaCount++;
}
}
// Handle no arguments (last opening parenthesis to the last closing one is empty)
if (commaCount === 0 && funcStr.substring(lastParen + 1, i).trim().length === 0) {
return 0;
}
return commaCount + 1;
}
Here are a few tests I tried it on: https://jsfiddle.net/ekzuvL0c/
Here is a function to retrieve the 'length' of a function (expression or object) or an arrow function expression (afe). It uses a regular expression to extract the arguments part from the stringified function/afe (the part between () or before =>) and a regular expression to cleanup default values that are strings. After the cleanups, it counts the comma's, depending on the brackets within the arguments string.
Note This will always be an approximation. There are edge cases that won't be covered. See the tests in this Stackblitz snippet
const determineFnLength = fnLenFactory();
console.log(`fnTest.length: ${determineFnLength(fnTest)}`);
function fnTest(a,
b,
c = 'with escaped \' quote and, comma',
d = "and double \" quotes, too!" ) { console.log(`test123`); }
function fnLenFactory() {
const fnExtractArgsRE = /(^[a-z_](?=(=>|=>{)))|((^\([^)].+\)|\(\))(?=(=>|{)))/g;
const valueParamsCleanupRE = /(?<=[`"'])([^\`,].+?)(?=[`"'])/g;
const countArgumentsByBrackets = params => {
let [commaCount, bracketCount, bOpen, bClose] = [0, 0, [...`([{`], [...`)]}`]];
[...params].forEach( chr => {
bracketCount += bOpen.includes(chr) ? 1 : bClose.includes(chr) ? -1 : 0;
commaCount += chr === ',' && bracketCount === 1 ? 1 : 0; } );
return commaCount + 1; };
const extractArgumentsPartFromFunction = fn => {
let fnStr = fn.toString().replace(RegExp(`\\s|function|${fn.name}`, `g`), ``);
fnStr = (fnStr.match(fnExtractArgsRE) || [fn])[0]
.replace(valueParamsCleanupRE, ``);
return !fnStr.startsWith(`(`) ? `(${fnStr})` : fnStr; };
return (func, forTest = false) => {
const params = extractArgumentsPartFromFunction(func);
const nParams = params === `()` ? 0 : countArgumentsByBrackets(params);
return forTest ? [params, nParams] : nParams;
};
}

Missing Letter Function - Why is it returning undefined?

I'm doing one of the bonfires on Free Code Camp and I'm close to the end, but there's one last bit I can't figure out!
The function should take a string and return what letter is missing (based on the alphabet a-z). It works fine except when the letter that's missing is 'i', where it returns undefined.
I put an additional if statement in to check that when the missing letter is 'i', it meets the criteria of the other if statement (and therefore should execute those lines of code) and it matched, so I've no idea why it would return undefined.
function fearNotLetter(str) {
missingLetter = '';
charCode = 0;
for (i = 0; i < str.length -1 ; i++) {
charCode = str.charCodeAt(i);
if (str.charCodeAt(i + 1)-charCode == 2) {
missingLetter = str.charCodeAt(i)+1;
missingLetter = String.fromCharCode(missingLetter);
} else {
missingLetter = undefined;
}
}
console.log(missingLetter);
return missingLetter;
}
fearNotLetter("abcdefghjklmno");
Really appreciate any help anyone can give.
Thanks in advance.
Because you are setting the value in every round without a missing letter to undefined - even if you found one in the loop before.
I suggest to declare all variable before use with var keyword and initialize missingLetter with undefined.
Then you can break the loop if the missing letter is found.
function fearNotLetter(str) {
var missingLetter = undefined,
charCode,
i;
for (i = 0; i < str.length - 1 ; i++) {
charCode = str.charCodeAt(i);
if (str.charCodeAt(i + 1) - charCode == 2) {
missingLetter = String.fromCharCode(charCode + 1);
break;
}
}
return missingLetter;
}
console.log(fearNotLetter("abcdefghjklmno"));
Try this, you are missing to break the loop once you get the missing letter and in the next iteration missing letter is set to undefined.
function fearNotLetter(str) {
missingLetter = '';
charCode = 0;
for (i = 0; i < str.length -1 ; i++)
{
charCode = str.charCodeAt(i);
if (str.charCodeAt(i + 1)-charCode == 2) {
missingLetter = str.charCodeAt(i)+1;
missingLetter = String.fromCharCode(missingLetter);
break;
}
else
{
missingLetter = undefined;
}
}
console.log(missingLetter);
return missingLetter;
}
fearNotLetter("abcdefghjklmno");

Cannot read property length null error when used with regular expressions

I'm a javascript beginner doing some CodeWars.com questions. I came across this question and I'm stuck due to a "cannot read property length null" error. I've tried to look up that error and can't find what the problem is in my program.
The assignment is:
"Check to see if a string has the same amount of 'x's and 'o's. The method must return a boolean and be case insensitive. The string can contains any char."
And this is what I've written so far:
function XO(str) {
var x = "x";
var o = "o";
var numX = str.match(/x/gi).length;
var numO = str.match(/o/gi).length;
while(str.indexOf(x) > -1 || str.indexOf(o) > -1) {
if(numX == numO){
return true;
}
}
if (numX === -1 && numO === -1){
return true;
}
}
XO("xoxo");
The assignment also says that if there is neither an X or an O then the program should return true.
This will not give you that error. When there are no matches, the match function returns null and you cannot get the length of null. A few extra lines solves this issue.
function XO(str) {
var x = "x";
var o = "o";
var numX = 0;
var numO = 0;
var xMatch = str.match(/x/gi);
var oMatch = str.match(/o/gi);
if (xMatch) {
numX = xMatch.length;
}
if (oMatch) {
numO = oMatch.length;
}
while(str.indexOf(x) > -1 || str.indexOf(o) > -1) {
if(numX == numO){
return true;
} else {
return false;
}
}
if (numX === -1 && numO === -1){
return true;
} else {
return false;
}
}
console.log(XO("ddd"));
I think you are making this problem more complex than it has to be.
All you need to do is make the string lowercase(to account for case insensitive), traverse the string, and when it finds an x, add 1 to a counter, and when you find and o, decrease 1 from the counter.
If it ends at 0, you return true, else you return false. There's no need for regexes
function XO(str){
var count = 0;
str = str.toLowerCase();
for(var i = 0; i < str.length; i++){
if(str[i] === 'x') count++;
if(str[i] === 'o') count--;
}
return count === 0 ? true : false;
}
Yes you have to check the return value of match is not null before checking the length property. However
while(str.indexOf(x) > -1 || str.indexOf(o) > -1) {
if(numX == numO){
return true;
}
}
looks like an infinite loop if either string contains lower case 'x' or 'o' and there are a different number of each.
More simply:
function XO(str)
{ var matchX = str.match(/x/gi);
var matchY = str.match(/o/gi);
return (matchX && matchY) ? matchX.length == matchY.length : !matchX && !matchY;
}

Categories

Resources