Output a large nested array with both sub-arrays and number objects - javascript

I am keeping track of each round of hands/results dealt in a blackjack game. I need to output each "round" as a single line. There are 'x' number of rounds. I am storing the results for each round in a big array. My problem is I have 2 arrays within my big array and 2 numeric. I need to output each of the 4 'objects' per line, as round results. I cannot figure out how to 'parse' the non-numeric array objects mixed with the numeric objects. Should I just create two arrays, one object and one numeric and output them separately?
Output goal is 1st line:
3,2,9,6;10,2,6;3,10
and so on for each round, one line.
<script>
var ph = [3,2,9,6]; var dh = [10,2,6]; var seq = 3, var bet = 10; var result;
allhands.push(ph);allhands.push(dh);allhands.push(seq);allhands.push(bet)
//allhands looks like this:[[3,2,9,6], [10,2,6], 3,10]
function showallhands(){
for (e = 0;e<allhands.length;e++){
for (f = 0; allhands[e][f];f ++){
result += allhands[e] + allhands[e][f]+";"+"<br >" ;
}
}
return result;
}
</script>
result = showallhands();
document.getElementById("ALLhands").innerHTML = result;

One approach is to create a game object then store the hands in it:
function Game() {
this.ph = [3, 2, 9, 6];
this.dh = [10, 2, 6];
this.seq = 3;
this.bet = 10;
this.getHands = function () {
return this.ph + ';' + this.dh + ';' + this.seq + ';' + this.bet + ';<br>';
};
};
var games = [];
games.push(new Game());
games.push(new Game());
games.push(new Game());
var result = "";
function showallhands() {
for (e = 0; e < games.length; e++) {
result += games[e].getHands();
}
return result;
}
result = showallhands();
document.getElementById("ALLhands").innerHTML = result;
If you want to keep the array and not use OOP, I think this would do the trick:
var arr = [
[3, 2, 9, 6],
[10, 2, 6], 3, 10, "hello"
];
arr.forEach(function each(item) {
if (Array.isArray(item)) {
item.forEach(each);
} else {
console.log(item);
}
});

Related

Splicing string values using functions and loops and storing as an array

I have a list of numbers that is a string value using a loop I want to split this string into different variables in an array, the first of length 3 and the 6 of length 7 and the last of length 3. How can this be done using functions and loops.
We could do something like this:
let str = '000111111122222223333333444444455555556666666mmmm';
// Defines the lengths we're using
let lengths = [3,7,7,7,7,7,7,3];
let index = 0;
let result = lengths.reduce((acc,n) => {
acc.push(str.slice(index, index += n));
return acc;
} , [])
console.log(result);
You could map the sub strings.
var str = '000111111122222223333333444444455555556666666mmmm',
lengths = [3, 7, 7, 7, 7, 7, 7, 3],
result = lengths.map((i => l => str.slice(i, i += l))(0));
console.log(result);
Here's one way to do that:
let theArray = document.getElementById('theArray');
let theVariable = document.getElementById('theVariable');
let targetString = "122333444455555666666";
let dataSizes = [1, 2, 3, 4, 5, 6];
var result = [];
var pos = 0;
dataSizes.forEach( (size) => {
result.push(targetString.substr(pos, size));
pos += size;
});
theArray.textContent = result.toString();
let [one, two, three, four, five, six] = result;
theVariables.textContent = `${one}-${two}-${three}-${four}-${five}-${six}`;
a generic way of doing this will be, if you want in a variable you can use subStringLengthMaps key, :-
let str="abcdefghijklmnopqrstu";
let subStringLengthMap={a:3, b:7, c:7 , d:3};
//making pure funciton
var getStrings = function(str, subStringLengthMap){
let result =[];
Object.keys(subStringLengthMap).forEach(function(key){
let temp = str.slice(0, subStringLengthMap[key]);
result.push(temp);
str = str.replace(temp,'');
})
return result;
}
//call the function
console.log(getStrings(str, subStringLengthMap))

Finding addenth on array - JS

I created a function that will find pairs to add the two numbers that will be equal to the sum.
function findingSum(arr, sum){
var firstElement = [];
var difference = [];
var final = [];
var convertArr = arr.map(function(item){
return parseInt(item, 10);
});
for(var i = 0; i < convertArr.length; i++){
difference.push(sum - convertArr[i]); // subtracted sum from each convertArr item
if(difference[i] + convertArr[i] === sum){ // check if convertArr item was added to difference item === sum
firstElement.push(convertArr[i]); // if so add the convertArritem to the result array
}
if(firstElement[i] + convertArr[i] == sum){
final.push(firstElement[i], convertArr[i]);
}
}
return final;
}
var addNumbers = findingSum([3, 34, 4, 12, 5, 2], 9);
console.log(addNumbers); // --> [4, 5]
So what I did is that I try to get the difference of convertArr[i] and the sum and put them in a difference variable. Then I tried to see if adding difference[i] from the original array will give me the sum. If so I'll add them on firstElement array and try to add each value to the original array and finally push them along with it's addenth if the sum was attain. So when you add this two you'll get the sum.
For some reason my logic doesn't work and it does'nt push things on both firstElement and final array. Can anyone help me with this?>
You could use a hash table for visited values.
var findingSum = function (array, s) {
var a, i,
hash = Object.create(null);
for (i = 0; i < array.length; i++) {
a = array[i];
if (hash[s - a]) {
return [s - a, a];
}
if (!hash[a]) {
hash[a] = true;
}
}
};
console.log(findingSum([3, 34, 4, 12, 5, 2], 9)); // [4, 5]

JavaScript: Count instances of specific integers in a string

OKAY, so I have a bunch of numbers in a div, lets say something like...
<div id="countme">7, 5, 6, 0, 3, 0, 5, 3, 3, 2, 8</div>
And I want to use JavaScript to return...
The specific number, and
The number of times that number occurred in the div
Example Output: "(2,0),(1,2),(3,3),(2,5),(1,6),(1,7),(1,8)"
Explained: Zero appears two times, two appears one time, three appears three times, etc...
I've tried the following...
var str = document.getElementById('countme').innerText;
var match = str.match(/7/g);
var match1 = str.match(/5/g);
alert(match.length);
alert(match1.length);
But I need it to display the number it searched for, and I need everything to be in one alert.
Any thoughts?
Thanks! :)
JSBIN: https://jsbin.com/tesezoz/1/edit?js,console
var str = "7, 5, 6, 0, 3, 0, 5, 3, 3, 2, 8";
// first get the numbers
var m = str.split(', ').map(Number);
// turn it into an object with counts for each number:
var c = m.reduce(function(a, b) {
a[b] = ++a[b] || 1;
return a;
}, {});
// now you have an object that you can check for the count
// which you can alert... its the c variable
Try this...
var str = "7, 5, 6, 0, 3, 0, 5, 3, 3, 2, 8";
str = str.replace(/\s/g, "");
str = str.split(",");
var result = {};
str.forEach(function(value) {
if (result[value]) {
result[value]++;
}
else {
result[value] = 1;
}
});
var output = "";
for(value in result) {
output += (output == "" ? "" : ",") + "(" + value + "," + result[value] +")";
}
alert(output);
It splits the string and removes any whitespace, so you're left with an array (and no assumption that the delimiter is consistent).
It then creates an object representing each value and the count.
It finally converts that into an output, similar to the one in your example.
Here is the Answer
var str = document.getElementById('countme').innerText;
var array = JSON.parse("[" + str+ "]");
var counts = {};
array.forEach(function(x) { counts[x] = (counts[x] || 0) + 1; });
console.log(counts);
I think this is almost as efficient as you can get. It also serves as a general count unique matches method:
var testString = document.getElementById('countme').innerText;
count = {};
var regX = /(\d+)/g;
var res;
while (res = regX.exec(testString )) {
count[res[0]] = (count[res[0]] !== undefined ? ++count[res[0]] : 1)
};

JavaScript array reduce start from index

This problem has been bugging me for a while now and I can't seem to find an answer in web.
Is it possible to use Array reduce method starting from a certain index?
simple example
var studentGrades = ["John Doe", "Some School", 6, 7, 8, 7, 9, 9];
If I need to loop over only integers in studentGrades, I can do that with a simple for loop
for(var i = 2; i < studentGrades.length; i++) {
// do stuff here ...
}
But let's say I would need get an average grade which is sum of all integers divided by integers count. If Array contained only integers, then there would be no problem using reduce.
var onlyIntegersArr = [5,2,3,4];
var averageGrade = onlyIntegersArr.reduce(function(a,b){
return a + b;
}) / onlyIntegersArr.length;
However if I know that for whatever reasons I need to skip the first two Array elements and start from index Array[2].
So for example I would apply reduce to studentGrades, but only starting from index studentGrades[2].
Is that possible with reduce?
Thank you for solutions, I like slice approach, but I prefer not using a new method in this case.
e.g.
var average = studentGrades.reduce(function(a,b,i){
return i >= 2 ? a+b : 0;
}) / (studentGrades.length - 2);
reduce's 3rd argument is an index, here is the fiddle
var averageGrade = onlyIntegersArr.reduce(function (a, b, c) {
if (c >= 2) {
return a + b;
} else {
return 0;
}
});
if array has more non-numeric items after second index then check this fiddle
var studentGrades = ["John Doe", "Some School", 6, 7, 8, 7, 9, 9, "Some School"];
var averageGrade = studentGrades.reduce(function (a, b, c) {
if (c >= 2 && !isNaN(b)) {
return a + b;
} else if (c >= 2) {
return a + 0;
} else {
return 0;
}
})
alert(averageGrade);
If you know for a fact that you want to skip the first n elements, you can use Array#slice
Using ES2015 Arrow Function
var sum = array.slice(n).reduce((a, b) => a + b);
var studentGrades = ["John Doe", "Some School", 6, 7, 8, 7, 9, 9];
var sum = studentGrades.slice(2).reduce((a, b) => a + b);
document.body.innerHTML = 'SUM is = ' + sum;
In ES5, the same code can be written using anonymous function.
var sum = array.slice(n).reduce(function(a, b) {
return a + b;
});
var studentGrades = ["John Doe", "Some School", 6, 7, 8, 7, 9, 9];
var sum = studentGrades.slice(2).reduce(function(a, b) {
return a + b;
});
document.body.innerHTML = 'SUM is = ' + sum;
for the case you mentioned, of only adding up numeric values, regardless of where in the array they are - you could do something like
var sum = array.reduce(function(result, v) {
return result + (parseFloat(v) || 0);
}, 0);
var studentGrades = ["John Doe", "Some School", 6, 7, 8, 7, 9, 9];
var sum = studentGrades.reduce(function(result, v) {
return result + (parseFloat(v) || 0);
}, 0);
document.body.innerHTML = 'SUM is = ' + sum;
If you're sure you always need only index 2 onwards, then this is sufficient
var onlyIntegersArr = studentGrades.slice(2);
var averageGrade = onlyIntegersArr.reduce(function(a,b){
return a + b;
}) / onlyIntegersArr.length;
If, however, you want to get all integers, then you need to filter the array
var onlyIntegersArr = studentGrades.filter(function(val) {
return (val === parseInt(val, 10));
});
var averageGrade = onlyIntegersArr.reduce(function(a,b){
return a + b;
}) / onlyIntegersArr.length;
Why do you overcomplicate things? Why not:
function avg(arr)
{
var sum = 0;
var l = 0;
for(var i = 0; i < arr.length; i++)
{
if(isNaN(1*arr[i])) continue;
sum += arr[i];
l++;
}
return sum/l;
}
Maybe you need to think about keeping the data in object, where all the grades are in a separate array. And other data be in properties. You can serialize it from the array you have, and then work with the object.

Extracting the most duplicate value from an array in JavaScript (with jQuery)

I have several array to deal with. I need to extract the most duplicate value from each array.
From [3, 7, 7, 7], I need to find the value 7. Each array size is 4. For now, I don't have to think about when the most duplicate values are more than one such as [3, 7, 7, 7]. All the values are a number.
I looked around the web. I found several ways to make an array to become uniq(). But I haven't found a way to get the duplicate value. I am using jQuery, but raw JavaScript is fine for this task.
Not perfect in terms of efficiency, but does the job:
var nums = [3, 7, 7, 7];
var freqs = {};
var max_index;
var max_value = -1/0; // Negative infinity.
$.each(nums, function(i, v) {
if (freqs[v] != undefined) {
freqs[v]++;
} else {
freqs[v] = 1;
}
});
$.each(freqs, function(num, freq) {
if (freq > max_value) {
max_value = freq;
max_index = num;
}
});
if (max_index != undefined) {
alert("Most common element is " + max_index + " with " + max_value + " repetition(s).");
}
​
Here's a simpler and faster version using only JavaScript:
var arr = [3, 7, 7, 7, 10, 10, 8, 5, 5, 5, 5, 20, 20, 1];
var counts = {}, max = 0, res;
for (var v in arr) {
counts[arr[v]] = (counts[arr[v]] || 0) + 1;
if (counts[arr[v]] > max) {
max = counts[arr[v]];
res = arr[v];
}
}
alert(res + " occurs " + counts[res] + " times");
Note that this is a much more efficient since you're looping over the data once, if you're sorting very large arrays this will start to matter.
Here's a quick example using javascript:
function mostFrequent(arr) {
var uniqs = {};
for(var i = 0; i < arr.length; i++) {
uniqs[arr[i]] = (uniqs[arr[i]] || 0) + 1;
}
var max = { val: arr[0], count: 1 };
for(var u in uniqs) {
if(max.count < uniqs[u]) { max = { val: u, count: uniqs[u] }; }
}
return max.val;
}
A quick note on algorithmic complexity -- because you have to look at each value in the array at least once, you cannot do better than O(n). This is assuming that you have no knowledge of the contents of the array. If you do have prior knowledge (e.g. the array is sorted and only contains 1s and 0s), then you can devise an algorithm with a run time that is some fraction of n; though technically speaking, it's complexity is still O(n).
Array.prototype.mostFreq=function(){
var what, a= this.concat(), ax, freq,
count, max=0, limit= a.length/2;
while(a.length){
what= a.shift();
count=1;
while((ax= a.indexOf(what))!= -1){
a.splice(ax,1); // remove counted items
++count;
}
// if any item has more than half the array, quit counting
if(count> limit) return what;
if(count> max){
freq= what;
max= count;
}
}
return freq;
}
var a=[1,1,2,5,4,2,7,7,1,1,1,3,7,7,3,4,3,7,3,5,6,2,3,1,1,7,7,2,4,3,6,7,6,6]
alert(a.mostFreq())
Another solution can be based on Array.reduce():
var arr = [1,1,2,5,4,2,10,10,1,1,1,3,10,10,3,4,3,10,3,5,6,2,3,1,1,10,10,2,4,3,6,10,6,6];
var result = arr.reduce(function(acc, e) {
acc[e] = (acc[e] || 0) + 1;
if (acc[e] > acc.mostFreq.freq) {
acc.mostFreq.value = e;
acc.mostFreq.freq = acc[e];
}
return acc;
}, {"mostFreq": {"value": 0, "freq": 0}}).mostFreq;
console.log('The most duplicated elements is: ' + JSON.stringify(result));

Categories