return value 0 instead of undefined - javascript

for (var i = 0; i < memberGroup.length; i++) {
subMemberType.push(memberGroup[i]["membershipType"])
}
var subMemTypeCount = [];
while (true) {
subMemberType.forEach(element => {
subMemTypeCount[element] = (subMemTypeCount[element] || 0) + 1;
});
console.log("\t\truby: " + subMemTypeCount["Ruby"]);
console.log("\t\tgold: " + subMemTypeCount["Gold"]);
console.log("\t\tplatinum: " + subMemTypeCount["Platinum"]);
console.log("\t\tdiamond: " + subMemTypeCount["Diamond"]);
break;
}
Output:
ruby: 2
gold: 2
platinum: undefined
diamond: 1
What I am trying to achieve is to print out each membership type "ruby", "gold", "platinum", & "diamond".
I used a forEach to loop through the array subMemberType to count the number of duplicated membership type.
memberGroup[i]["membershipType"] is an 2D array, with a constructor membershipType.
My problem is that when I pushed memberGroup[i]["membershipType"] to array subMemberType, there wasn't the "platinum" membership type. Hence, when I loop through the array using for each to find the duplicated membership type, it returns as undefined. However, I would like it to return "0" instead of "undefined". Is there anyway I can do that?

Instead of setting subMemTypeCount to an empty array (which should have been an object), set it to an object containing those for properties with the value 0. Then you can also reduce the body of the .forEach() to subMemTypeCount[element]++.
As an aside: a while-loop that loops unconditionally and breaks unconditionally after the first iteration, is fully redundant.
const subMemberType = ['Ruby', 'Diamond', 'Ruby', 'Gold', 'Gold'];
var subMemTypeCount = {'Ruby': 0, 'Gold': 0, 'Platinum': 0, 'Diamond': 0};
subMemberType.forEach(element => {
subMemTypeCount[element]++;
});
console.log("\t\truby: " + subMemTypeCount["Ruby"]);
console.log("\t\tgold: " + subMemTypeCount["Gold"]);
console.log("\t\tplatinum: " + subMemTypeCount["Platinum"]);
console.log("\t\tdiamond: " + subMemTypeCount["Diamond"]);
Alternatively you can use the Nullish coalescing operator (??), or the Logical OR (||) in case the nullish coalescing operator isn't supported.
const subMemberType = ['Ruby', 'Diamond', 'Ruby', 'Gold', 'Gold'];
var subMemTypeCount = {};
subMemberType.forEach(element => {
subMemTypeCount[element] = (subMemTypeCount[element] || 0) + 1;
});
console.log("\t\truby: " + (subMemTypeCount["Ruby"] ?? 0));
console.log("\t\tgold: " + (subMemTypeCount["Gold"] ?? 0));
console.log("\t\tplatinum: " + (subMemTypeCount["Platinum"] ?? 0));
console.log("\t\tdiamond: " + (subMemTypeCount["Diamond"] ?? 0));

If you want to handle undefined elements in one line, you can try something like:
console.log ("\t\tplatinum: " + (subMemTypeCount["Platinum"])?subMemTypeCount["Platinum"]:0);
This is basically checking if it is defined or not, If defined -> prints, else 0

Related

Am I correct about .toFixed() and decimals?

I gave an example of using .tofixed() with math, functions, and arrays, to a beginner coder friend who has been reviewing these topics in his class.
const bananaX = 9;
const bananaY = 2.9768;
bananaArray = [bananaX , bananaY];
console.log("X before array = " + bananaX);
console.log("Y before array = " + bananaY + '\n')
console.log("X,Y after array = " + bananaArray + '\n')
console.log("Value of X in array: " + bananaArray[0]+ '\n')
console.log("Value of Y in array: " + bananaArray[1]+ '\n')
function bananaDivision (bananaArray){
console.log("Value of X after function = " + bananaX);
console.log("Value of Y after function = " + bananaY + '\n')
let bananaDivided = Math.abs(bananaX/bananaY );
console.log (`X divided by Y = + ${bananaDivided}` + '\n')
let bananaFixed = bananaDivided.toFixed(2);
console.log("After using .toFixed(2) : " + bananaFixed + '\n');
};
bananaDivision();
They were understanding and following along no problem.
Then they asked me - "What if we put a decimal in the .toFixed ?"
So I ran:
const bananaX = 9;
const bananaY = 2.9768;
bananaArray = [bananaX , bananaY];
console.log("X before array = " + bananaX);
console.log("Y before array = " + bananaY + '\n')
console.log("X,Y after array = " + bananaArray + '\n')
console.log("Value of X in array: " + bananaArray[0]+ '\n')
console.log("Value of Y in array: " + bananaArray[1]+ '\n')
function bananaDivision (bananaArray){
console.log("Value of X after function = " + bananaX);
console.log("Value of Y after function = " + bananaY + '\n')
let bananaDivided = Math.abs(bananaX/bananaY );
console.log (`X divided by Y = + ${bananaDivided}` + '\n')
let bananaFixed = bananaDivided.toFixed(2);
let bananaFixed1 = bananaDivided.toFixed(.69420);
let bananaFixed2 = bananaDivided.toFixed(1.69420);
console.log("After using .toFixed(2) : " + bananaFixed + '\n');
console.log("After using .toFixed(.69420) : " + bananaFixed1 + '\n');
console.log("After using .toFixed(1.69420) : " + bananaFixed2 + '\n');
};
bananaDivision();
I explained it as that .toFixed is looking at the first number within the () and that the decimals are ignored.
Am I correct? For my own curiousity, is there a crazy way to break .toFixed() so that it actually uses decimals? I'm experimenting atm but wanted to know if someone already figured that out.
I explained it as that .toFixed is looking at the first number within the () and that the decimals are ignored.
This would be correct. That is essentially what happens.
For full correctness, the input of toFixed() will be converted to an integer. The specification states that the argument must first be converted to a number - NaN will be converted to a zero. Numbers with a fractional part will be rounded down.
Which means that if you pass any number, you essentially get the integer part of it.
It also means that non-numbers can be used:
const n = 3;
console.log(n.toFixed("1e1")); // 1e1 scientific notation for 10
You're close, since toFixed() expects an integer it will handle converting decimal numbers before doing anything else. It uses toIntegerOrInfinity() to do that, which itself uses floor() so the number is always rounded down.
Most of Javascript handles type conversion implicitly, so it's something you should really understand well if you don't want to run into problems. There's a free book series that explains that concept and a lot of other important Javascript knowledge very well, it's called You Don't Know JS Yet.
just a demo how .tofixed works !!!!!!
function roundFloat(x, digits) {
const arr = x.toString().split(".")
if (arr.length < 2) {
return x
}else if(arr[1] === ""){
return arr[0]
}else if(digits < 1){
return arr[0]
}
const st = parseInt(x.toString().split(".")[1]);
let add = false;
const rudgt = digits
const fX = parseInt(st.toString().split("")[rudgt]);
fX > 5 ? add = true : add = false
nFloat = parseInt(st.toString().split("").slice(0, rudgt).join(""))
if (add) {
nFloat += 1
}
const repeat0 = (() => {
if (rudgt - st.toString().length < 0) {
return 0
}
return rudgt - st.toString().length
})()
const output = x.toString().split(".")[0] + "." + nFloat.toString() + "0".repeat(repeat0);
return output
}
console.log(roundFloat(1.200, 2))

Find repeated letters in an array (javascript)

I'm new on this and javascript. I've tried to solve an exercise that consist to find repeated letter a in an array. The way to do is use basic structures (no regex neither newer ways of javascript (only ES5)). I need to do it this way to understand the bases of the language.
The output must be this:
//Captain America, the letter 'C' => 2 times.
//Captain America, the letter 'A' => 4 times.
//Captain America, the letter 'I' => 2 times.
I'm not looking for the solution, only the way to do it and its logical structures. Any suggestions are welcome.
My way but it doesn't work:
function duplicateLetter(name) {
var newArray = [];
for (var i=0; i<name.length; i++) {
console.log(name[i].indexOf(newArray));
if (name[i].indexOf(newArray) === 0) {
newArray.push(name[i]);
}
}
console.log(newArray);
//console.log(name + ", the letter '" + (newArray[0]).toUpperCase() + "' => " + newArray.length + " times");
}
duplicateLetter("Captain America");
function duplicateLetter(o) {
var arr = o.toUpperCase().split('');
var obj = {};
for(var v in arr) {
obj[arr[v]] = obj[arr[v]] || 0;
obj[arr[v]]++;
}
for(var v in obj) {
console.log(o + ", the letter '" + v + "' => " + obj[v] + ' times.');
}
}
duplicateLetter("Captain America");
The explanation:
We make the string upper case, then turn it into an array of letters.
We loop over the array, here, arr[v] becomes our letter, and:
If the key arr[v] doesn't exist in our object, we set it to 0.
We increment the value of the key arr[v] in our object (this causes obj['c'] to increment every time our letter is c. You can notice that this keeps track of the number of letters in our string.
We loop over the object v, printing the number of occurrences of each letter to console.
Note that this considers the space character as a letter. If you want an answer that doesn't, please specify so.
Here's a different answer that doesn't use objects and only counts letters (and not spaces or punctuation) to prove that everything is possible in more than one way.
// Not using objects and not counting anything but letters.
function duplicateLetter(o) {
var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var arr = o.toUpperCase().split('');
var count = [];
for(var v in arr) {
pos = letters.indexOf(arr[v]);
if(pos < 0) continue; // It wasn't a letter.
count[pos] = count[pos] || 0;
count[pos]++;
}
for(var v in count) {
if(!(count[v] > 0)) continue; // The letter never appeared.
console.log(o + ", the letter '" + letters[v] + "' => " + count[v] + ' times.');
}
}
duplicateLetter("Captain America");
I could probably also attempt an answer that doesn't use arrays at all!
Edit:
You can use for(a in b) loops to iterate arrays as well as objects. This is because an array is really just an object in which all enumerable properties have integer indices:
arr = [10,15,"hi"] is almost the same as arr = {'0' : 10, '1' : 15, '2' : "hi"} in the way Javascript works internally. Therefore, for (v in arr) will iterate over the array normally.
As requested, the same answer with normal for loops:
// Not using objects and not counting anything but letters.
function duplicateLetter(o) {
var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var arr = o.toUpperCase().split('');
var count = [];
for(var v = 0; v < arr.length; v++) {
pos = letters.indexOf(arr[v]);
if(pos < 0) continue; // It wasn't a letter.
count[pos] = count[pos] || 0;
count[pos]++;
}
for(var v = 0; v < count.length; v++) {
if(!(count[v] > 0)) continue; // The letter never appeared.
console.log(o + ", the letter '" + letters[v] + "' => " + count[v] + ' times.');
}
}
duplicateLetter("Captain America");
Note that nothing changed outside what was in the for brackets. The for-in notation is just easier for the human brain to comprehend, in my opinion, and is the reason I used it.
As for count[pos] = count[pos] || 0;, explaining why it works the way it does is extremely tedious, since it requires that you know precisely what the || operator does. So I'm just going to state what it does, without explaining it.
Basically, count[pos] = count[pos] || 0; is the same as:
if(count[pos]) { // If count[pos] evaluates to true.
count[pos] = count[pos]
} else { // count[pos] is false, '', null, undefined, 0, or any other value that evaluates to false.
count[pos] = 0;
}
Note that this works because at the start, count[pos] is undefined (count is an empty array), so it puts a 0 in it. If we find the letter again, count[pos] is defined, and is a positive value, and therefore evaluates to true, so we don't change it.
Just consider a = a || b to be equal to:
Put the default value of b into a if a is undefined (or evaluates to false by any other means).`
Make an object whose keys are the letters and values are the number of times that letter was repeated. For example,
'abbc' => {'a': 1, 'b': 2, 'c': 1}

the multiplication of a code between two numbers incorrectly outputting number

function showMultiples(num, numMultiples){
for(i=1; i<=numMultiples; i++){
var multiple = num + " x " + i + " = " + num * i;
}
return multiple;
}
console.log('showMultiples(2,8) returns: ' + showMultiples(2,8));
For this code, what the function should do is, by looking at num and numMultiples variable, it should give you the list of multiplication that is possible with the two numbers. Therefore the console should print out
2x1=2 2x2=4 2x3=6 2x4=8 2x5=10 2x6=12 2x7=14 2x8=16
However, this code prints out 2x8 = 16 any guess to why?
You're assigning the value to multiple then returning it in the end, when your loop has finished, meaning multiple will be 2x8. If you do a console.log(multiple) right under var multiple = num + " x " + i + " = " + num * i; you will see it print out correctly.
EDIT:
function showMultiples(num, numMultiples){
var result = [];
for(i=1; i<=numMultiples; i++){
result.push(num + " x " + i + " = " + num * i);
}
return result.join(' ');
}
Add results to an array and when the function completes, join the values inside the array and return the results.
You only have one print statement, and that is outside of the loop. If you want to print multiple times, you need to put the print statement inside of the loop, something like this:
function showMultiples(num, numMultiples) {
console.log(`showMultiples(${num}, ${numMultiples}) returns:`);
Array.from({length: numMultiples}, (v, k) => k + 1).
forEach(i => console.log(`${num}×${i} = ${num * i}`));
}
showMultiples(2, 8)
// showMultiples(2, 8) returns:
// 2×1 = 2
// 2×2 = 4
// 2×3 = 6
// 2×4 = 8
// 2×5 = 10
// 2×6 = 12
// 2×7 = 14
// 2×8 = 16
However, that is bad design. You shouldn't mix data transformation and I/O. It is much better to separate the two and build the data up first completely, then print it:
function showMultiples(num, numMultiples) {
return Array.from({length: numMultiples}, (v, k) => k + 1).
map(i => `${num}×${i} = ${num * i}`).
join(", ");
}
console.log(`showMultiples(2, 8) returns: ${showMultiples(2, 8)}`);
// showMultiples(2, 8) returns: 2×1 = 2, 2×2 = 4, 2×3 = 6, 2×4 = 8, 2×5 = 10, 2×6 = 12, 2×7 = 14, 2×8 = 16
This is much more idiomatic ECMAScript.

Using character codes to get frequency on words in a string, JavaScript

I'm trying to rewrite this frequency finding program in Javascript. Here is the Java code:
public class frequency {
public static void main(String[] args){
String S = "Temple University";
int[] p = new int[256];
for (char c :S.toCharArray()) {
p[c]++;
System.out.println(c +" shows up "+p[c] + " times");
}
Output:
T shows up 1 times
e shows up 1 times
m shows up 1 times
p shows up 1 times
l shows up 1 times
e shows up 2 times
shows up 1 times
U shows up 1 times
n shows up 1 times
i shows up 1 times
v shows up 1 times
e shows up 3 times
r shows up 1 times
s shows up 1 times
i shows up 2 times
t shows up 1 times
y shows up 1 times
However, my JavaScript implementation doesn't work at all:
function frequency(){
s = "Temple University";
str = s.split('');
p = [];
p.length = 256;
console.log("start");
for(c in str){
p[c]++;
console.log("inside" + c);
console.log(String.fromCharCode(c) + " shows up " + p[c] + "times");
}
}
It's late I've been trying to figure out why this JavaScript code is not working so I'm sorry if this post seems unpolished.
You can manipulate string directly as array and need a safe check for occurrence of chars else assign value 1.
So use a for loop for iterating over whole string can extract char as s[index] while using p[char] for occurrence frequency.
sample code follows
function frequency(){
s = "Temple University";
p = [];
console.log("start");
for(var i=0;i<s.length;i++){
if(!p[s[i]]){
p[s[i]] = 1;
}else{
p[s[i]]++;
}
console.log(s[i] + " shows up " + p[s[i]] + "times");
}
}
frequency()
Does this work for you? If so, you just weren't referencing the charCode but the index of the letter in the string..
function frequency() {
s = "Temple University";
str = s.split('');
p = [];
p.length = 256;
console.log("start");
for (c in str) {
var curChar = str[c];
var charCode = curChar.charCodeAt();
p[charCode] ? p[charCode]++ : p[charCode] = 1;
console.log(curChar + " shows up " + p[charCode] + " time(s)");
}
}
frequency()
The main reason this isn't working is that for loops work differently in Javascript than in Java. In Javascript, a for-in loop iterates through the properties of an object, not the indices of an array or string, so rather than for-in, you'd want to use a plain for loop, like so:
function getFrequencies(string) {
if (typeof(string) !== 'string') {
throw new Error('string argument is not of type string.');
}
var str = string.split('');
var frequencies = {};
for (var c = 0; c < str.length; c++) {
var charCode = String.fromCharCode(str[c]);
if (!frequencies[charCode]) {
frequencies[charCode] = 1;
} else {
frequencies[charCode]++;
}
}
return frequencies;
}
A couple tips: you would want to use a plain object ({}) instead of an array ([]), given that you're counting unique values. Secondly, there's no need to declare the length of an array in Javascript -- arrays are automatically resized as they grow, and the length property is readonly anyway.
You may do as follows;
var s = "Temple University",
fmap = Array.prototype.reduce.call(s,(p,c) => (p[c] ? p[c]++ : p[c] = 1,p),{});
for(var i in fmap) console.log(i, "shows up", fmap[i],"times.");
We are using an array functor Array.prototype.reduce() over a string by using a Function method .call(). So the first argument passed to .call() is the string s itself (designating the context to be called upon) and a callback ((p,c) => (p[c] ? p[c]++ : p[c] = 1,p)) for the second argument to be invoked per item (character) of the string. The .reduce() functor uses an empty object {} as an initial value which will be assigned to p, whereas c would be assigned to the first character in the first turn. It will generate a map called fmap like;
{ T: 1,
e: 3,
m: 1,
p: 1,
l: 1,
' ': 1,
U: 1,
n: 1,
i: 2,
v: 1,
r: 1,
s: 1,
t: 1,
y: 1 }
Then a for in loop traverses over the map keys and we display the obtained data by a console.log() instruction.

Converting mathematical operator as string argument to real operator in javascript

I am creating a program in javascript and I don't know how I can achieve following; My program takes argument such as "+","-" and other mathematical operators as string which I want to convert to real operators. For example (Pseudo-code):
function calc(a,b,c, op1,op2){
output=(a op1 b op2 c)
}
calc(2,3,4,"+","-")
Output should be now = 2+3-4.
However, I don't know in advance how many operators I will have and also the numbers. In other words, my objective is to replace 1,"+",2, "-",4,"+","(",5,"+",6,")".........and so on with 1+2-4+(5+6).....
How can I implement this in a nice manner?
Well, you could use eval but you can do simply this :
var funcs = {
'+': function(a,b){ return a+b },
'-': function(a,b){ return a-b }
};
function calc(a,b,c, op1,op2){
return funcs[op2](funcs[op1](a, b), c);
}
You can easily extend the funcs map with other operators.
I really would suggest using eval for this particular case:
eval("var res = " + 1 + "+" + 2 + "-" + 4 + "+" + "(" + 5 + "+" + 6 + ")");
console.log(res); //10
I know, I know, everone says you should avoid eval where possible. And they are right. eval has great power and you should only use it with great responsibility, in particular when you evaluate something, that was entered by the end user. But if you are careful, you can use eval and be fine.
This has been done very quickly, but should do the trick(JSFiddle here):
function executeMath() {
if (arguments.length % 2 === 0) return null;
var initialLength = arguments.length,
numberIndex = (initialLength + 1)/2,
numbers = Array.prototype.splice.call(arguments, 0, numberIndex),
operands = Array.prototype.splice.call(arguments, 0),
joiner = new Array(arguments.length);
for (var i = 0; i < numbers.length; i++) {
joiner[i*2] = numbers[i];
}
for (var i = 0; i < operands.length; i++) {
joiner[1+(i*2)] = operands[i];
}
var command = ("return (" + joiner.join('') + ");"),
execute = new Function(command);
console.log(command);
return execute();
}
console.log(executeMath(2, 3, 4, 5, "/", "+", "%"));

Categories