How many Odd and Even number are the in a array - javascript

I have created an Array with some numbers.
I want to find out how many even, and how many odd numbers it is in
this Array. I have to print it out like this: (this is just an example)
Even number: 6
Odd number: 7
I need to make a loop that count up how many it is off even and odd numbers.
This is what I have so far
<script>
window.onload = run;
var tall = [5,10,15,20,25,30,35,40,45,50];
function run() {
tall = [5,10,15,20,25,30,35,40,45,50];
liste(tall);
}
function liste(arr) {
var sumOdd = 0; // Odd 1, 3, 5 etc..
var sumPar = 0; // Even 2, 4, 6 etc..
for(var i = 0; i < arr.length; i++) {
if(arr[i] % 2 === 0) {
sumPar += arr.length;
}
else {
sumOdd += arr.length;
} // Even numbers // Odd numbers
document.getElementById("print").innerHTML = "Partall: " + sumPar + "<br />" + "Oddetall: " + sumOdd;
}
}
}
</script>
Its something that is wrong here, and I dont know what.

You could iterate with Array#reduce and count only the odds. For the rest just take the difference of the length of the array and the odds.
var tall = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50],
odd = tall.reduce(function (r, a) { return r + a % 2; }, 0),
even = tall.length - odd;
console.log('odd', odd);
console.log('even', even);

You were adding arr.length which is the array length. Instead you should simply increment the number
var tall = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50];
liste(tall);
function liste(arr) {
var sumOdd = 0;
var sumPar = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
sumPar++;
} else {
sumOdd++;
}
}
console.log("Odd : " + sumOdd);
console.log("Par : " + sumPar);
}

You always add the complete Length of the array to your variable
Try this instead of sumPar += arr.length;:
sumPar++;

Related

How can I sum array index values?

I am new to Javascript and at the moment I'm learning how "arrays" are used.
In my code below I have 12 numbers held by an array variable. Next, the for loop is iterating over the indexes to check which values have 2 or more digits, the while-loop then summarizes the digits (e.g. value '130' at index 8, will be 1+3+0=4).
Final step..and also where I'm stuck:
I need to sum up all the "new" index values and return the result in a variable.
With the numbers provided in the code, the result would be '50'.
Anyone have clue on how to do this? I've tried the conventional for-loop with sum += array[i], but it doesn't work.
var arrChars = [4, 2, 14, 9, 0, 8, 2, 4, 130, 65, 0, 1];
for (var i = 0; i < arrChars.length; i++) {
var digsum = 0;
while (arrChars[i] > 0) {
digsum += arrChars[i] % 10;
arrChars[i] = Math.floor(arrChars[i] / 10);
}
var sum = 0; // this last part won't work and I just get "nan", 12 times
for (var j = 0; j < arrChars.length; j++) {
sum += parseInt(digsum[j]);
}
console.log(sum); // desired output should be '50'
}
Move digsum outside and it will contain the sum of every number in it:
var arrChars = [4, 2, 14, 9, 0, 8, 2, 4, 130, 65, 0, 1];
var digsum = 0;
for (var i = 0; i < arrChars.length; i++) {
while (arrChars[i] > 0) {
digsum += arrChars[i] % 10;
arrChars[i] = Math.floor(arrChars[i] / 10);
}
}
console.log(digsum); // desired output should be '50'
I'd make this easy and just flatten the array of numbers into a string of digits, split that into an array of single digits, and add them together:
var arrChars = [4, 2, 14, 9, 0, 8, 2, 4, 130, 65, 0, 1];
console.log([...arrChars.join('')].reduce((agg, cur) => agg += +cur, 0));

Reset counter when not in range and sum progression

I have an arrays of numbers, and specified range if sequence continues (range rule was met between two numbers) then i add value to result and increase counter by one, else i reset the counter and add nothing to result on this step. Better show in an example:
const numbers = [1, 4, 5, 6, 7, 33, 44, 46]; // they are always going to be from smallest to bigger
const progress = [0, 10, 20, 30, 40, 50, 60]; // 70, 80, etc
let res = 0;
for (let i = 1, j = 0; i < numbers.length; i++) {
const range = numbers[i] - numbers[i - 1];
if (range <= 5) {
j += 1;
res += progress[j];
} else {
j = 0;
}
}
res; // 110
Is there better way to approach this problem?
Well, by looking at your code & the explanation you gave, I think you have incremented 'j' before you added progress for 'j'. that portion should be like following...
if (range <= 5) {
res += progress[j];
j += 1;
}
You have asked for a better approach. But it would help if you specified from which perspective/scenario you are looking for a better approach.
you can do the same with reduce method
const numbers = [1, 4, 5, 6, 7, 33, 44, 46]; // they are always going to be from smallest to bigger
const progress = [0, 10, 20, 30, 40, 50, 60]; // 70, 80, etc
let resp = 0;
const result = numbers.reduce((acc, rec, i, arr) => {
if (rec - arr[i - 1] <= 5) {
resp += 1;
acc = acc + progress[resp];
return acc;
}
resp = 0;
return acc;
}, 0);
result;
You can read more about reduce here
Hope it answers your question.
Happy coding!

Converting an array of numbers into a suitable regular expression

That's right. Unlike most questions, I am not trying to write a regular expression myself. I am trying to generate a regular expression (JavaScript flavoured, to be used in HTML5's pattern attribute).
Given an array of numbers, give a concise, fast, and correct regular expression that will only match the given input. I have already done part of the job, namely the ones [0-9]:
var ones = [0, 1, 2, 3, 4, 5, 8, 9],
onesRegex = "";
for (var i = 0; i < ones.length; i++) {
e = ones[i];
if (i > 0 && e == ones[i - 1] + 1) {
if (i != ones[i + 1] - 1) {
onesRegex += e + "]";
}
} else {
if (onesRegex != "") onesRegex += "|";
onesRegex += "[" + e + "-";
}
}
// Returns [0-5]|[8-9]
alert(onesRegex);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
This could then be used in an <input> (yes, jQuery is allowed):
$("input").attr("pattern", onesRegex);
The problem I am experiencing is that I am not sure how to continue. Ones are easy enough, as you see above. However, things get increasingly more difficult as soon as you start adding digits because you have to take into account so many things. For instance, you can have [112, 358, 359, 360, 361] which should result in (112|(3(5[8-9]|6[0-1]))) which is already quite extensive for only five numbers.
For my project, the maximum value is 500, so all values < 1000 should be parsable.
I have written quite a bit, but there's a lot to be done -- I need to get the logic behind it. So far my idea is to split the number in ones, tens, and hundreds, and treat them accordingly. Additionally, the appropriate function can waterfall down to other functions. For instance, parsing the number 512 could split it down into 5 and 12, 12 will go down to a function for decimals, and so on. That's the main idea, but the logic and structure is missing.
Here is what I have so far, but I also provide a JSFiddle which is a bit easier to work with.
var arr = [0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 18, 19, 20, 21, 105, 106, 107, 256, 257, 258, 259, 260],
onesArray = [],
tensArray = [],
hundredsArray = [];
// MAIN
function regexGenerator() {
orderSplitter(arr);
// Do stuff
// Should return finished Regex as a string
}
// Split input array in ones (1 digit), tens (2 digits), hundreds (3 digits)
function orderSplitter(numberArray) {
$(numberArray).each(function(index, element) {
if (element < 10) {
onesArray.push(element);
} else if (element < 100 && element > 9) {
tensArray.push(element);
} else if (element < 1000 && element > 99) {
hundredsArray.push(element);
}
});
}
/* Following functions expect an array as input */
function onesToRegex(ones) {
var onesRegex = "";
for (var i = 0; i < ones.length; i++) {
var e = ones[i];
if (i > 0 && e == ones[i - 1] + 1) {
if (i != ones[i + 1] - 1) {
onesRegex += e + "]";
}
} else {
onesRegex += "[" + e + "-";
}
}
return onesRegex;
}
function tensToRegex(tens) {
var tensRegex = "";
for (var j = 0; j < tens.length; j++) {
var f = tens[j],
ten = Math.floor(f / 10),
one = f - (ten * 10);
}
return tensRegex;
}
function hundredsToRegex(hundreds) {
var hundredsRegex = "";
for (var k = 0; k < hundreds.length; k++) {
var g = tens[j],
hundred = Math.floor(g / 100),
ten = Math.floor((g - (hundred * 100)) / 10),
one = g - (ten * 10);
}
return hundredsRegex;
}
As an alternative approach, consider using HTML5 <datalist>. This can be generated in JavaScript too.
var arr = [.......];
var datalist = document.createElement('datalist');
arr.forEach(function(num) {
var option = document.createElement('option');
option.value = num;
datalist.appendChild(option);
});
datalist.id = "numberlist";
document.body.appendChild(datalist);
// apply to input
someInputElement.setAttribute("list","numberlist");
Here's a demo for you: https://jsfiddle.net/960sjuhc/
A proposal with a tree.
Basically it has two parts
build tree with an object, where the length of the stringed numbers are the first key, and the rest are properties with one digit and an object.
build the regular expression string with iterating over the first key (the length) and start iter with the content of the property and the decremented length/depth of the following object.
function getRegex(array) {
function group(array) { // take array [0,1,3,4,5,6,8] return string '013-68'
return array.reduce(function (r, a, i, aa) {
if (!i || aa[i - 1] + 1 !== a) {
return r.concat([[a]]);
}
r[r.length - 1][1] = a;
return r;
}, []).map(function (a) {
return a.join(a[0] + 1 === a[1] ? '' : '-');
}).join('');
}
function iter(o, l) { // iterate an object
// get all keys form the object as sorted numbers
var keys = Object.keys(o).map(Number).sort(function (a, b) { return a - b; });
if (keys.length === 1) { // if just one key return the key and get the next level
return keys[0] + iter(o[keys[0]], l - 1);
}
if (keys.length > 1) { // if more than one key
// test the level
// if next level
// return parenthesis with all keys and their next levels separated with |
// if no level
// return grouped keys with brackets around
return l ?
'(' + keys.map(function (k) { return k + iter(o[k], l - 1); }).join('|') + ')' :
'[' + group(keys) + ']';
}
return '';
}
var tree = {};
array.forEach(function (a) {
var o, s = a.toString();
tree[s.length] = tree[s.length] || {};
o = tree[s.length];
s.split('').forEach(function (b) {
o[b] = o[b] || {};
o = o[b];
});
});
return '(' + Object.keys(tree).map(function (k) { return iter(tree[k], +k - 1); }).join('|') + ')';
}
document.write('<pre>' + getRegex([0, 1, 2, 3, 4, 5, 8, 9]) + '</pre>');
document.write('<pre>' + getRegex([100, 200, 212, 213, 214, 357]) + '</pre>');
document.write('<pre>' + getRegex([112, 358, 359, 360, 361]) + '</pre>');
document.write('<pre>' + getRegex([0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 18, 19, 20, 21, 105, 106, 107, 256, 257, 258, 259, 260]) + '</pre>');
As was pointed out in the comments, I should have had some fun with it -- and I followed your advice and here we are! My solution is probably not as efficient as Nina Scholz's answer (not tested, but that answer just looks more... detailed) but it is better readable in my opinion and it was a lot of fun to make -- and not at all as hard as I had thought, once I got my head around it.
It's on JSFiddle. And also here as a snippet. I did my best commenting the some-what harder parts, but most of it should be quite straightforward, though in retrospect I could've chosen some better variable names. Comments are welcome!
var arr = [0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 18, 19, 20, 21, 105, 106, 107, 256, 257, 258, 259, 260],
onesArray = [],
tensArray = [],
tensMultiArray = {},
hundredsArray = [],
hundredsMultiArray = {};
// MAIN
function regexGenerator(arr) {
orderSplitter(arr);
var onesRegexString = onesToRegex(onesArray);
var tensRegexString = tensToRegex(tensArray);
var hundredsRegexString = hundredsToRegex(hundredsArray);
// Don't forget start/end points ^$
var regex = "(^(" + onesRegexString + ")$)|(^(" + tensRegexString + ")$)|(^(" + hundredsRegexString + ")$)";
$(".result code").text(regex);
}
regexGenerator(arr);
// Split input array in ones (1 digit), tens (2 digits), hundreds (3 digits)
// Can be extended to include others
function orderSplitter(numberArray) {
$(numberArray).each(function(index, element) {
if (element < 10) {
onesArray.push(element);
} else if (element < 100 && element > 9) {
tensArray.push(element);
} else if (element < 1000 && element > 99) {
hundredsArray.push(element);
}
});
}
/* Following functions expect an array as input */
function onesToRegex(ones) {
var onesRegex = "";
for (var i = 0; i < ones.length; i++) {
var e = ones[i];
// If this element is not the first element, and it is equal to
// the previous number + 1
if (i > 0 && e == (ones[i - 1] + 1)) {
// If this element is NOT equal to the next element - 1
// Will also return true if next item does not exist
if (e != (ones[i + 1] - 1)) {
onesRegex += e + "]";
}
}
// If this item is a (new) first item in a list
else {
if (onesRegex != "") onesRegex += "|";
onesRegex += "[" + e + "-";
}
}
return onesRegex;
}
function tensToRegex(tens) {
var tensRegex = "";
// Loop the array and break the number down in digits
// E.g. 13 -> ten = 1; one = 3
$(tens).each(function(index, element) {
var ten = Math.floor(element / 10),
one = element - (ten * 10);
// Push items to associative arrays (objects)
if (!(ten in tensMultiArray)) {
tensMultiArray[ten] = [one];
} else {
tensMultiArray[ten].push(one);
}
});
var i = 0;
for (var ten in tensMultiArray) {
if (tensMultiArray.hasOwnProperty(ten)) {
// Each iteration is a new number, meaning it is an *alternative*
// Hence the pipe
if (i > 0) tensRegex += "|";
tensRegex += ten;
// The `one` digits belonging to ten (e.g. 1 and 2 for 11 and 12) is an array
// Therefore we can send it down to onesToRegex to be processed
if (tensMultiArray[ten].length > 1) {
tensRegex += "(" + onesToRegex(tensMultiArray[ten]) + ")";
} else {
tensRegex += tensMultiArray[ten][0];
}
i++;
}
}
return tensRegex;
}
function hundredsToRegex(hundreds) {
var hundredsRegex = "";
// Loop the array and break the number down in hundreds and rest
// E.g. 128 -> hundred = 1; rest = 28
$(hundreds).each(function(index, element) {
var hundred = Math.floor(element / 100),
rest = element - (hundred * 100);
// Push items to associative arrays (objects)
if (!(hundred in hundredsMultiArray)) {
hundredsMultiArray[hundred] = [rest];
} else {
hundredsMultiArray[hundred].push(rest);
}
});
var i = 0;
for (var hundred in hundredsMultiArray) {
if (hundredsMultiArray.hasOwnProperty(hundred)) {
// Each iteration is a new number, meaning it is an *alternative*
// Hence the pipe
if (i > 0) hundredsRegex += "|";
hundredsRegex += hundred;
// The `rest` digits belonging to hundred (e.g. 28 and 29 for 128 and 129)
// is an array. Therefore we can send it down to tensToRegex to be processed
// In turn, tensToRegex will also send its ones through to onesToRegex
if (hundredsMultiArray[hundred].length > 1) {
hundredsRegex += "(" + tensToRegex(hundredsMultiArray[hundred]) + ")";
} else {
hundredsRegex += hundredsMultiArray[hundred][0];
}
i++;
}
}
return hundredsRegex;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>
Generate Regular Expression based on an input array
</h1>
<p>
In this example the input is <code>[0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 18, 19, 20, 21, 105, 106, 107, 256, 257, 258, 259, 260]</code>. The result is:
</p>
<p class="result"><code></code></p>

How to push multiples of a number to array?

How would one push multiples of a number to an array? For example, if the input is (6), I want to create an array that holds [6, 12, 18, 24, 30, 36, etc...]
The most intuitive method to me does not work.
for (var i = 0; i < 10; i++) {
firstArray.push(arr[0] *= 2);
}
This multiplies the number that comes before it by 2, causing an exponential growth. [14, 28, 56, 112, 224, 448, 896, 1792, etc.]
How would one achieve this?
Problem:
The problem in the code, as commented by Pranav is the use of multiplication by two in the for loop.
Using i iterator index can solve the problem.
firstArray.push(6 * (i + 1));
As i is starting from 0, i + 1 will give the number which is 1-based.
Another Approach:
First add the number
var num = 6,
arr = [num];
Then add the number which is double of the previous in the array.
for (var i = 1; i < 10; i++) {
arr.push(arr[i - 1] + num);
}
var arr = [6];
for (var i = 1; i < 10; i++) {
arr.push(arr[i - 1] + arr[0]);
}
console.log(arr);
The same thing can also be done in single line using for loop.
var arr = [];
for (let i = 0, num = 6; i < 10; i++, num += 6) {
arr.push(num);
}
console.log(arr);
You can use map:
function multiplyArrayElement(num) {
return num * 2;
}
numbers = [6, 12, 18, 24, 30, 36];
newArray = numbers.map(multiplyArrayElement);
https://jsfiddle.net/25c4ff6y/
It's cleaner to use Array.from. Just beware of its browser support.
Array.from({length: 10},(v,i) => (i + 1) * 6)
try this one
for (var i = 0; i < 10; i++) {
firstArray.push(arr[0] * (i+1));
}
var arr = [];
var x = 6; //Your desired input number
var z;
for(var i=1;i<10;i++){
z = (x*i);
arr.push(z);
}
console.log(arr);
"One line" solution with Array.fill and Array.map functions:
var num = 6;
var arr = new Array(10).fill(0).map(function(v, k){ return num *(k + 1); });
console.log(arr); // [6, 12, 18, 24, 30, 36, 42, 48, 54, 60]

Javascript : Loop through an array starting and ending at different indexs

I have a very large array of objects — around 30000.
randomStart = Math.floor( Math.random() * arr.length )
I'm selecting a random range from the total length.
what I want to do is loop through the array beginning at randomStart and ending at randomStart + n.
Note:
This array must stay intact, because it's too computationally expensive to re-render the entire set.
What's the best way to go about this ? What looping paradigm should be used : for, while, etc
Instead of setting var i = 0 at the beginning of your for loop, simply set it to your starting index, then instead of setting the stopping condition to i < array.length, set it to i < ending_index.
This works because you then iterate i through all indexes between the start and end_index, just like in a "normal" for loop you iterate from 0 to the end of the array.
If you are trying to process the array in batches try this. You will have to adjust the batch limit based on your preference.
function ProcessLargeArray() {
var largeArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36];
var batchLimit = 10;
for (var startIndex = 0; startIndex < largeArray.length; startIndex = startIndex + batchLimit) {
ProcessBatch(largeArray, startIndex, GetEndIndex(startIndex, batchLimit, largeArray.length));
}
}
function GetEndIndex(startIndex, batchLimit, arrayLength) {
var endIndex = startIndex + batchLimit;
if (endIndex > arrayLength) {
return arrayLength;
}
return endIndex;
}
function ProcessBatch(someArray, startIndex, endIndex) {
console.log("Start Batch from " + startIndex + " to " + endIndex);
for (var i = startIndex; i < endIndex; i++) {
console.log(someArray[i]);
}
console.log("Ending Batch from " + startIndex + " to " + endIndex);
}
var arr = [1,2,3,4];
var batchSize = 2;
var randomStart = Math.floor(Math.random() * (arr.length - batchSize));
for (var i = randomStart; i < randomStart + batchSize ; i++) {
///Code here
}

Categories