Related
Let's say we want to count the NaN's in a javascript array. We can use
let arr = [...Array(100)].map( (a,i) => i %10==0 ? NaN : i )
console.log(arr)
> [NaN, 1, 2, 3, 4, 5, 6, 7, 8, 9, NaN, 11, 12, 13, 14, 15, 16, 17, 18, 19, NaN, 21, 22, 23, 24, 25, 26, 27, 28, 29, NaN, 31, 32, 33, 34, 35, 36, 37, 38, 39, NaN, 41, 42, 43, 44, 45, 46, 47, 48, 49, NaN, 51, 52, 53, 54, 55, 56, 57, 58, 59, NaN, 61, 62, 63, 64, 65, 66, 67, 68, 69, NaN, 71, 72, 73, 74, 75, 76, 77, 78, 79, NaN, 81, 82, 83, 84, 85, 86, 87, 88, 89, NaN, 91, 92, 93, 94, 95, 96, 97, 98, 99]
let nans = arr.map( aa => isNaN(aa) ? 1 : 0).reduce((acc,a) => acc+a)
console.log(nans)
> 10
That does work.. but it is a bit challenging to remember the reduce() machinery every time. Is there a more concise construct by applying a predicate as so:
arr.count( a => isNan(a))
You can have just a single .reduce where the accumulator is the number of NaNs found so far:
const arr = [...Array(100)].map( (a,i) => i %10==0 ? NaN : i );
const nans = arr.reduce((a, item) => a + isNaN(item), 0);
console.log(nans);
You can filter out the elements that are not NaN.
arr.filter(isNaN).length
//or
arr.filter(function(it){ return isNaN(it); }).length
With forEach loop instead of map and reduce
const nanCount = (arr, count = 0) => (
arr.forEach((num) => (count += isNaN(num))), count
);
const arr = [NaN, 0, 1, 3 , NaN];
console.log(nanCount(arr));
Or while for even bigger...
const arr = [...Array(1e6)].map((a, i) => i % 10 == 0 ? NaN : i);
let
i = arr.length,
nans = 0;
while (i--) {
nans += isNaN(arr[i]);
}
console.log(nans.toExponential());
const arr = [...Array(100)].map((a, i) => i % 10 == 0 ? NaN : i);
const count = (arr, predicate) => {
let c = 0, i = arr.length;
while (i--) c += predicate(arr[i]);
return c
};
const
nans = count(arr, x => isNaN(x)),
sevens = count(arr, x => x % 7 === 0);
console.log(`nans: ${nans}, sevens: ${sevens}`);
Hi when i try to declare var highScore = 0; inside for loop in chrome console it says Uncaught SyntaxError: Unexpected token 'var' so what can i do for that here is my code:
var scores = [60, 50, 60, 58, 54, 54,
58, 50, 52, 54, 48, 69,
34, 55, 51, 52, 44, 51,
69, 64, 66, 55, 52, 61,
46, 31, 57, 52, 44, 18,
41, 53, 55, 61, 51, 44];
var totalTest = scores.length;
function bubbleScore() {
for (var i = 0; var highScore = 0; i < scores.length; i++) {
console.log("Bubble solution #" + i + " score: " + scores[i]);
if (scores[i] > highScore) {
highScore = scores[i];
}
}
console.log("Bubbles tests: " + scores.length);
return console.log("Highest bubble score: " + highScore);
}
bubbleScore();
As #Nick said earlier for loop got three-section like for (initialization; condition; post-expression) so the thing you are trying here (declaring two variables) in the for loop is illegal. Since you want to iterate (and not defining it at the first of loop) your highScore variable in your for loop, it is better to do it this way:
var highScore = 0;
for (var i = 0; i < scores.length; i++) {
console.log("Bubble solution #" + i + " score: " + scores[i]);
if (scores[i] > highScore) {
highScore = scores[i];
}
}
But if you insist on such a thing you can do it like this:
for (var i = 0, highScore = 0; i < scores.length; i++) {
console.log("Bubble solution #" + i + " score: " + scores[i]);
if (scores[i] > highScore) {
highScore = scores[i];
}
}
Here is the full version:
var scores = [60, 50, 60, 58, 54, 54,
58, 50, 52, 54, 48, 69,
34, 55, 51, 52, 44, 51,
69, 64, 66, 55, 52, 61,
46, 31, 57, 52, 44, 18,
41, 53, 55, 61, 51, 44
];
var totalTest = scores.length;
function bubbleScore() {
for (var i = 0, highScore = 0; i < scores.length; i++) {
console.log("Bubble solution #" + i + " score: " + scores[i]);
if (scores[i] > highScore) {
highScore = scores[i];
}
}
console.log("Bubbles tests: " + scores.length);
return console.log("Highest bubble score: " + highScore);
}
bubbleScore();
You have to use symbol ; to declare
(init conditions ; continue condition ; action after iteration)
In this case it will be like
for (var i = 0, highScore = 0; i < scores.length; i++) {
or
for (let score of scores) {
P.S to find max element try Math.max(...scores); or for old browsers Math.max.apply(null, scores);
const scores = [60, 50, 60, 58, 54, 54,
58, 50, 52, 54, 48, 69,
34, 55, 51, 52, 44, 51,
69, 64, 66, 55, 52, 61,
46, 31, 57, 52, 44, 18,
41, 53, 55, 61, 51, 44];
function bubbleScore() {
console.log("Bubbles tests: " + scores.length);
return console.log("Highest bubble score: " + Math.max(...scores));
}
bubbleScore();
You can try this
var scores = [60, 50, 60, 58, 54, 54,
58, 50, 52, 54, 48, 69,
34, 55, 51, 52, 44, 51,
69, 64, 66, 55, 52, 61,
46, 31, 57, 52, 44, 18,
41, 53, 55, 61, 51, 44];
var totalTest = scores.length;
var highScore = 0;
function bubbleScore() {
for (var i = 0; i < totalTest; i++) {
console.log("Bubble solution #" + i + " score: " + scores[i]);
if (scores[i] > highScore) {
highScore = scores[i];
}
}
console.log("Bubbles tests: " + scores.length);
return console.log("Highest bubble score: " + highScore);
}
bubbleScore();
Given a range, how is it possible in javascript to find the missing number in an unordered array? For example, if I know the range of an array is [48,79] and the array is:
[56, 76, 48, 69, 60, 68, 57, 58, 52,
72, 61, 64, 65, 66, 73, 75, 77,
49, 63, 50, 70, 51, 74, 54, 59,
78, 79, 71, 55, 67]
The missing number/output would be 62,53.
You should try this
function findNumbers(arr) {
var sparse = arr.reduce((sparse, i) => (sparse[i]=1,sparse), []);
return [...sparse.keys()].filter(i => i && !sparse[i]);
}
var myArr = [56, 76, 48, 69, 60, 68, 57, 58, 52,
72, 61, 64, 65, 66, 73, 75, 77,
49, 63, 50, 70, 51, 74, 54, 59,
78, 79, 71, 55, 67]
var res= findNumbers(myArr );
console.log(res);
EDIT: by the time I posted this, Vinay Kaklotar had posted a much better solution for the OPs updated question.
I would iterate until the missing value's index isn't found:
var arr = [1,2,3,4,5,7,8,9,10];
var i = 1;
while(arr.indexOf(i) !== -1) {
i++;
}
console.log(i);
The above was an answer to the original question before OP edited it. Below is a solution to the updated question.
I'm iterating through the array and comparing each item to a new sequence (n). Every time a missing number is found, it's added to the missing array.
var arr = [1, 2, 4, 5, 6, 9];
var missing = [];
var n = 1;
for (var i = 0; i < arr.length; i++) {
if (arr[i] !== n) {
missing.push(n);
i--;
}
n++;
}
console.log(missing);
I'm trying to create a bot that interprets an array (exp table) and returns the exp difference between two levels.
I'm new to JavaScript still, so I'm sure it's something within my code, I have tried various combinations of array.find, array[x] and moving formula into variables. I just cannot seem to figure it out.
var xparray = [1, 0, 2, 300, 3, 900, 4, 2000, 5, 3700, 6, 6000, 7, 10200, 8, 16200, 9, 23550, 10, 33480, 11, 45280, 12, 60880, 13, 80480, 14, 104180, 15, 130580, 16, 161080, 17, 196480, 18, 236980, 19, 282680, 20, 333680, 21, 390280, 22, 454180, 23, 525580, 24, 604680, 25, 691780, 26, 786980, 27, 896780, 28, 1021580, 29, 1161780, 30, 1317680, 31, 1480180, 32, 1656080, 33, 1845680, 34, 2049180, 35, 2267080, 36, 2499400, 37, 2749300, 38, 3017100, 39, 3303300, 40, 3608200, 41, 3932200, 42, 4272400, 43, 4629200, 44, 5002900, 45, 5393700, 46, 5801900, 47, 6239500, 48, 6707000, 49, 7205000, 50, 7734000, 51, 8598000, 52, 9656400, 53, 10923600, 54, 12478800, 55, 14350800, 56, 16568400, 57, 19160400, 58, 22155600, 59, 25582800, 60, 29470800, 61, 33940800, 62, 38813800, 63, 44129800, 64, 49938800, 65, 56302800, 66, 63297800, 67, 71019800, 68, 79594800, 69, 89187800, 70, 100013800, 71, 112462800, 72, 126343800, 73, 141899800, 74, 159398400, 75, 179148400, 76, 201478400, 77, 226818400, 78, 255468400, 79, 288218400, 80, 325868400];
var tn = (String(message).length);
// !xp 40 60
var a = (String(message).length)-3;
var b = (String(message).length)-3;
var c = (String(message).length)-5;
var d = (String(message).length)-2;
var t0 = message.substring(b, a); //(-3,-3)
var t1 = message.substring(c, b); //(-5,-3)
var t2 = message.substring(d, tn); //(-2,0)
var na = function(t0){return (t0*2)-1};
var nb = function(t1){return (t1*2)-1};
var nc = function(t2){return (t2*2)-1};
var T1 = xparray.find(function(element) {
return element > t2});
var T2 = xparray.find(function(element) {
return element > t0;
});
var T3 = xparray.find(function(element) {
return element > t1;
});
var t3 = function(T1, T2, T3) {
if (message.length = 7) {
return T1 - T2;
} else {
return T1 - T3;
}
};`
I expect this to pull values 40 and 60 from the end of the string '!xp 40 60', interpret the array and pull the next value after 40 (3608200) and the value after 60 (29470800), then preform a calculation to take the 40 value away from the 60 value (29470800-3608200). So far I think the issue lies around the T1, T2 and T3 values as they are always returning 1, or the value in the array after 1 (300).
With one dimensional array:
You can just get the index of the lvl in the array with indexOf and then take the next value (which is the xp needed for that lvl). After that subtract the two and you are good to go:
var xparray = [1, 0, 2, 300, 3, 900, 4, 2000, 5, 3700, 6, 6000, 7, 10200, 8, 16200, 9, 23550, 10, 33480, 11, 45280, 12, 60880, 13, 80480, 14, 104180, 15, 130580, 16, 161080, 17, 196480, 18, 236980, 19, 282680, 20, 333680, 21, 390280, 22, 454180, 23, 525580, 24, 604680, 25, 691780, 26, 786980, 27, 896780, 28, 1021580, 29, 1161780, 30, 1317680, 31, 1480180, 32, 1656080, 33, 1845680, 34, 2049180, 35, 2267080, 36, 2499400, 37, 2749300, 38, 3017100, 39, 3303300, 40, 3608200, 41, 3932200, 42, 4272400, 43, 4629200, 44, 5002900, 45, 5393700, 46, 5801900, 47, 6239500, 48, 6707000, 49, 7205000, 50, 7734000, 51, 8598000, 52, 9656400, 53, 10923600, 54, 12478800, 55, 14350800, 56, 16568400, 57, 19160400, 58, 22155600, 59, 25582800, 60, 29470800, 61, 33940800, 62, 38813800, 63, 44129800, 64, 49938800, 65, 56302800, 66, 63297800, 67, 71019800, 68, 79594800, 69, 89187800, 70, 100013800, 71, 112462800, 72, 126343800, 73, 141899800, 74, 159398400, 75, 179148400, 76, 201478400, 77, 226818400, 78, 255468400, 79, 288218400, 80, 325868400];
var message = '!xp 40 60';
var lvls = [parseInt(message.split(' ')[1]), parseInt(message.split(' ')[2])]; // Getting the lvls in question
lvls = lvls.map(l => xparray[xparray.indexOf(l)+1]); // Getting the xp values in question
console.log(lvls[1] - lvls[0]); // Substract xp values
With two-dimensional array (with use of a map to simplify):
Map that two dimensional array to a Map or use a Map in the first place. Then just get the correct xp value by the lvl key.
var xparray = [[1, 0], [2, 300], [3, 900], [4, 2000], [5, 3700]];
var xpMap = new Map(xparray); // Map constructor takes the two dimensional array (key=lvl, value=xp)
var message = '!xp 2 3';
var lvls = [parseInt(message.split(' ')[1]), parseInt(message.split(' ')[2])]; // Getting the lvls in question
lvls = lvls.map(l => xpMap.get(l)); // Just map it by getting the value for the key
console.log(lvls[1] - lvls[0]); // Substract xp values
I cant figure out a condition that could check for all 6 numbers. I tried using || but its just messy and i know thats not correct.
Using the following Array, create variable called numThrees with the value [13, 23, 33, 43, 53, 63, 73]
var numArray = [13, 15, 17, 23, 25, 27, 33, 35, 37, 43, 45, 47, 53, 55, 57, 63, 65, 67, 73, 75, 77];
var numThrees = [];
for (i = 0; i < numArray.length; i++) {
if (numArray[i] === 13) {
numThrees[i] = numArray[i];
};
};
document.getElementById('q7').innerHTML = numThrees;
you can just check if the remainder of the number with 10 is 3 ,which is for your condition(13,23,33,43,53,63 and 73)
var numArray = [13, 15, 17, 23, 25, 27, 33, 35, 37, 43, 45, 47, 53, 55, 57, 63, 65, 67, 73, 75, 77];
var numThrees = [];
for (i = 0; i < numArray.length; i++) {
if (numArray[i]%10==3) {
numThrees.push(numArray[i]);
};
};
document.getElementById('q7').innerHTML = numThrees;
<div id="q7">
</div>
Hope it helps
There are several ways to do this. Here are two that use different logic to extract the right numbers:
You can do this the manual way:
var numArray = [13, 15, 17, 23, 25, 27, 33, 35, 37, 43, 45, 47, 53, 55, 57, 63, 65, 67, 73, 75, 77];
var numThrees = [];
for(var i = 0; i < numArray.length; ++i){
// Turn the current array element into a string
var strVal = numArray[i].toString();
// If that string ends with "3" add it to the new array:
strVal[strVal.length-1] === "3" ? numThrees.push(numArray[i]) : "";
}
console.log(numThrees);
You can use the Array.prototype.filter method:
var numArray = [13, 15, 17, 23, 25, 27, 33, 35, 37, 43, 45, 47, 53, 55, 57, 63, 65, 67, 73, 75, 77];
// The Array.prototype.filter method iterates every item in
// a given array and allows you to implement any logic you
// like and return any value from the original array you like
// into a new array that will be a filter of the first one.
var numThrees = numArray.filter(function(element){
// Check the current element being iterated for one of
// a designated set of values and return that element
// into the filtered array if it is a match.
switch(element){
case 13:
case 23:
case 33:
case 43:
case 53:
case 63:
case 73:
return element;
default:
break;
}
});
console.log(numThrees);
Your instructions are a bit arbitrary, but here's a more efficient way of doing it:
var numArray = [13, 15, 17, 23, 25, 27, 33, 35, 37, 43, 45, 47, 53, 55, 57, 63, 65, 67, 73, 75, 77];
var numThrees = [];
for (i = 0; i < numArray.length; i+=3) {
numThrees.push(numArray[i]);
};
document.getElementById('q7').innerHTML = numThrees;
Since we can observe that the given array has the desired values at certain indices which are equally spaced apart, there's no need to iterate through the entire array.
Your directions don't specify if we can do it based on the assumption that we know what's in the original array and what index. If this is the case, then you do need to iterate through the array in some fashion, and then test to see if each index contains your desired value.
I'm assuming this is an acceptable solution.
Edit: Based on my understanding (and likely what's more efficient.) I don't think that, in this case, we should be iterating through the entire array when its hard coded. We know what values are in the array, and at what position. It just so happens that the numbers you want are evenly spaced in the numArray, which is even more reason to not test each value to some condition.
Hope this makes sense.
Do you need items ending in 3, or every third item in the array??
Using Array.filter is the most efficent way to achieve either by:
returning values with a remainder of 3 when divisible by 10.
var numArray = [13, 15, 17, 23, 25, 27, 33, 35, 37, 43, 45, 47, 53, 55, 57, 63, 65, 67, 73, 75, 77];
var numThrees = numArray.filter(function(val){
return val % 10 === 3;
});
console.log(numThrees);
If however, you need get every third element in the array you can do the following which returns the item if the iterator has no remainder when divided by 3
var numArray = [13, 15, 17, 23, 25, 27, 33, 35, 37, 43, 45, 47, 53, 55, 57, 63, 65, 67, 73, 75, 77];
var numThrees = numArray.filter(function(val, i) {
return i % 3 === 0;
});
console.log(numThrees);
Convert the array to list and use Contains
var list = numArray.ToList();
if (list.Contains(thing))
...