Working on my first JS app, BlackJack, and have been stuck at this point for a while: what I'm trying to do is if var a is called from the array it could = 11 or 1 depending on the total value. Is there no way to change the value of an item in an array after you set up said array?
var j = 10;
var q = 10;
var k = 10;
var a;
var totalPlayer = 12;
var cards = [2, 2, ..., a, a, a];
function processIt() {
playerCard1 = cards[48]; //this is calling for var a form the array
if (totalPlayer > 11) {
a = 1;
} else {
a = 11;
}
var cpu1 = document.getElementById("cpu1");
cpu1.innerHTML = playerCard1; //this is calling for var a form the array
}
I have also tried converting it to a sting then back to a var, failed.
If I'm reading correctly, you've set up your array
var cards = [2, 2, ..., a, a, a];
and now you want to change all those a's?
Unfortunately (since a is a primitive) you'll have to manually change the values in your array that currently equal a, and set them to the updated value.
for (var i = 0, max = cards.length; i < max; i++)
if(cards[i] === a)
cards[i] = newValue;
EDIT
As hop points out, just be aware that if a is equal to 2, then all indexes in your array equal to 2 will be replaced—those first few indexes that you manually set to 2, and also those indexes at the end that you set to a. But since you say that a will either be 1 or 11, it looks like you've set things up in such a way that this won't be an issue.
You cannot do what you are expecting this way.
var a = 1;
var cards = [2, 2, a, a, a];
a = 5;
alert(cards); // This should print 2,2,5,5,5 is what you expect.
// But, it will only print 2,2,1,1,1
You can store all the indexes for which you set the value as 'a'. After all, you are constructing the array and it should be no hurdle for you.
In our case, you will have another array
var aIndexes = [2,3,4];
Then you can change the value of cards array like below.
if (totalPlayer > 11) {
a = 1;
} else {
a = 11;
}
for(var i =0; i< aIndexes.length; i++){
cards[i] = a;
}
The following line:
var cards = [2, 2, ..., a, a, a];
...copies the value of a into the last three array positions. Those values have no relationship with a itself. Changing a later has no effect on the array. It must be updated manually:
if (totalPlayer > 11) {
a = 1;
} else {
a = 11;
}
cards.splice(-3, 3, a, a, a);
var a;
…
var cards = [2, 2, ..., a, a, a];
puts the value of a at the time of creation of the Array instance as element of the array, not some sort of pointer to a. It is equivalent here to
var cards = [2, 2, ..., undefined, undefined, undefined];
You can either modify the array directly, as others have pointed out, or store references to an Object instance in the array (references are values). Modifying a property of that Object instance would modify it for all references to the Object instance then.
var a = {
toString: function () { return String(this.valueOf()); },
valueOf: function () { return this.value; }
};
// …
var cards = [2, 2, ..., a, a, a];
function processIt()
{
var playerCard1 = cards[48];
if (totalPlayer > 11)
{
a.value = 1;
}
else
{
a.value = 11;
}
var cpu1 = document.getElementById("cpu1");
cpu1.innerHTML = playerCard1;
}
Accessing a in string or numeric expression context would then yield the value of the value property of the Object instance referred to by a:
/* y + a.valueOf() */
var x = y + a;
/* z + a.toString() */
var y = z + String(a);
You must decide whether either approach makes sense in your case, as I do not know Blackjack well, and your question is rather confused.
BTW, you have forgotten to declare playerCard1 which causes it to leak into outer execution contexts or causes a runtime error (ES 5.x strict mode). I have fixed it for you. In general, you want to reduce the number of global variables to the absolute necessary minimum.
Related
I'm new to JS and am trying to create a simple 'swap array elements if array A element is bigger than array B element' function. In the swapIndexes function, I don't understand why I can't define the variables as shown in the comments. For example, it works if it state arrA[c] rather than let a = arrA[c].
Why does this happen? Can anyone give some beginner tips on how best to go about something like this? My code feels verbose. Thanks for any help here.
var arrA = [0, 1, 2, 7, 6],
arrB = [0, 1, 2, 5, 7],
indexesToSwap = [],
aValuesToSwap = [],
bValuesToSwap = [],
needSwapping = false;
arrA.forEach(getSwappableIndexesAndValues);
indexesToSwap.forEach(swapIndexes);
function getSwappableIndexesAndValues(c, i) {
let b = arrB[i];
if (c > b) {
needSwapping = true;
indexesToSwap.push(i);
aValuesToSwap.push(b);
bValuesToSwap.push(c);
}
}
function swapIndexes(c, i) {
//let a = arrA[c]; fails why???
//let b = arrB[c]; fails why???
//a = aValuesToSwap[i]; fails why???
//b = bValuesToSwap[i]; fails why???
arrA[c] = aValuesToSwap[i];
arrB[c] = bValuesToSwap[i];
}
console.log(arrA);
console.log(arrB);
In javascript, when you create a variable from a given index in an array, This will create a new memory space containing a copy of the value at this index. The newly created variable will not point to the content of the array and thus, modifying this variable will not modify the content of the array.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
indexesToSwap has all the information you need to swap. The swap value arrays (aValuesToSwap, bValuesToSwap) are greatly complicating matters and are wholly unnecessary.
Regardless of the values to swap arrays, swapping is a fundamental operation and typically involves a simple temporary, e.g.
temp = arrA[i];
arrA[i] = arrB[i];
arrB[i] = temp;
Discarding the complexities, here's an alternative to the function getSwappableIndexesAndValues
function getSwappableIndexes(c, i) {
if (c > arrB[i])
indexesToSwap.push(i);
}
And a simplified swap function
function swapIndexes(c, i) {
let temp = arrA[c];
arrA[c] = arrB[c];
arrB[c] = temp;
}
I have to say further though that the use of Array.forEach wildly complicates the entire solution. Unless this is an assignment, using a simple for-loop is best here.
// swaps values between arrays where the value in
// array a is greater than the value in array b
//
function swapIfGreaterThan(a,b) {
for(let i = 0; i < a.length && i < b.length; i++) {
if(a[i] > b[i]) {
let temp = a[i];
a[i] = b[i];
b[i] = temp;
}
}
}
var arrA = [0, 1, 2, 7, 6],
arrB = [0, 1, 2, 5, 7],
indexesToSwap = [],
aValuesToSwap = [],
bValuesToSwap = [],
needSwapping = false;
arrA.forEach(getSwappableIndexesAndValues);
indexesToSwap.forEach(swapIndexes);
function getSwappableIndexesAndValues(c, i) {
let b = arrB[i];
if (c > b) {
needSwapping = true;
indexesToSwap.push(i);
aValuesToSwap.push(b);
bValuesToSwap.push(c);
}
}
function swapIndexes(c, i) {
//let a = arrA[c]; fails why???
//let b = arrB[c]; fails why???
//a = aValuesToSwap[i]; fails why???
//b = bValuesToSwap[i]; fails why???
arrA[c] = bValuesToSwap[i];
arrB[c] =aValuesToSwap[i];
console.log( arrA[c], arrB[c]);
console.log( aValuesToSwap[i], bValuesToSwap[i]);
}
console.log(arrA);
console.log(arrB);
It is not possible array values and primitive data type values are different. If you try with the array of the object your attempt will be correct.
I need to write a program that, when given a list of integers, it finds all 2-pairs of integers that have the same product. i.e. a 2-pair is 2 distinct pairs of integers lets say [(a,b),(c,d)] where a*b = c*d but a ≠ b ≠ c ≠ d.
The range of integers should be from 1 to 1024. What I would like to implement is that when the web page is opened the user is prompted by a pop up in which he will enter the array of integers, i.e [1,2,3,7,8,9,6] etc for instance from the input [1,2,3,7,8,9,6] the output should be [(9,2),(3,6)] since both evaluate to 18.
The coding I did so far is very basic and can be seen below. What I've done so far is the pop-up box alert the input etc, but can't seem to understand how to make the program check for the pairs and give the sum. Thanks in advance to this community who's helping me out to better understand and learn javascript!
I've done my fair bit of research below, definitely different question than mine but have gone through them.
Find a pair of elements from an array whose sum equals a given number
https://www.w3resource.com/javascript-exercises/javascript-array-exercise-26.php
Code:
function evaluate() {
const input = prompt("Please enter the array of integers in the form: 1,2,3,1")
.split(',')
.map(item => item.trim());
function pairs(items) {
}
if (input == "" || input == null) {
document.writeln("Sorry, there is nothing that can be calculated.");
} else {
document.writeln("Your calculation is: ");
document.writeln(pairs(input) + " with a starting input string of: " + input);
}
}
evaluate()
You could iterate the array and a copy of the array beginning by the actual index plus one for getting the products. Store the result in an object with product as key.
Then get the keys (products) of the object, filter it to get only the results with two or more products.
var array = [1, 2, 3, 7, 8, 9, 6],
result = {},
pairs;
array.forEach(function (a, i) {
array.slice(i + 1).forEach(function (b) {
(result[a * b] = (result[a * b] || [])).push([a, b]);
});
});
pairs = Object
.keys(result)
.filter(function (k) { return result[k].length >= 2; })
.map(function(k) { return result[k]; });
console.log(pairs);
We could mutate the equation:
a * b = c * d | : b
a = c * d : b
So actually we just need to get all different combinations of three numbers (b, c, d) and check if the result (a) is also in the given range:
while(true){
// shuffle
const [b, c, d] = items;
const a = c * d / b;
if(items.includes(a + ""))
return true;
}
return false;
Now you only need to shuffle the array to go through all different combinations. You can find an algorithm here
Assuming that you are given an array such as [1,2,3,7,8,9,6] and a value 18 and you need to find pairs that multiply to 18 then, use the following approach
Convert them to a map - O(n)
var inputArr = [1,2,3,7,8,9,6];
var map = inputArr.reduce( (acc, c) => {
acc[ c ] = true; //set any truthy value
return acc;
},{});
Iterate an inputArr and see if its compliment is available in the map - O(n)
var output = [];
var mulValue = 18;
inputArr.forEach( s => {
var remainder = mulValue/s;
if ( map[s] && map[remainder] )
{
output.push( [ s, remainder ] );
map[s] = false;
map[remainder] = false;
}
});
Demo
var inputArr = [1, 2, 3, 7, 8, 9, 6];
var map = inputArr.reduce((acc, c) => {
acc[c] = true; //set any truthy value
return acc;
}, {});
var output = [];
var mulValue = 18;
inputArr.forEach(s => {
var remainder = mulValue / s;
if (map[s] && map[remainder]) {
output.push([s, remainder]);
map[s] = false;
map[remainder] = false;
}
});
console.log(output);
You can try something like this:
Idea:
Loop over the array to compute product. Use this iterator(say i) as get first operand(say op1).
Now again loop over same array but the range will start from i+1. This is to reduce number of iteration.
Now create a temp variable that will hold product and operand.
On every iteration, add value to product in hashMap.
Now loop over hashMap and remove any value that has length that is less than 2.
function sameProductValues(arr) {
var hashMap = {};
for (var i = 0; i < arr.length - 1; i++) {
for (var j = i + 1; j < arr.length; j++) {
var product = arr[i] * arr[j];
hashMap[product] = hashMap[product] || [];
hashMap[product].push([arr[i], arr[j]]);
}
}
for(var key in hashMap) {
if( hashMap[key].length < 2 ) {
delete hashMap[key];
}
}
console.log(hashMap)
}
sameProductValues([1, 2, 3, 7, 8, 9, 6])
I've been trying to find a reasonably concise way to set the dimensions of an empty multidimensional JavaScript array, but with no success so far.
First, I tried to initialize an empty 10x10x10 array using var theArray = new Array(10, 10 10), but instead, it only created a 1-dimensional array with 3 elements.
I've figured out how to initialize an empty 10x10x10 array using nested for-loops, but it's extremely tedious to write the array initializer this way. Initializing multidimensional arrays using nested for-loops can be quite tedious: is there a more concise way to set the dimensions of empty multidimensional arrays in JavaScript (with arbitrarily many dimensions)?
//Initializing an empty 10x10x10 array:
var theArray = new Array();
for(var a = 0; a < 10; a++){
theArray[a] = new Array();
for(var b = 0; b < 10; b++){
theArray[a][b] = new Array();
for(var c = 0; c < 10; c++){
theArray[a][b][c] = 10
}
}
}
console.log(JSON.stringify(theArray));
Adapted from this answer:
function createArray(length) {
var arr = new Array(length || 0),
i = length;
if (arguments.length > 1) {
var args = Array.prototype.slice.call(arguments, 1);
while(i--) arr[i] = createArray.apply(this, args);
}
return arr;
}
Simply call with an argument for the length of each dimension.
Usage examples:
var multiArray = createArray(10,10,10); Gives a 3-dimensional array of equal length.
var weirdArray = createArray(34,6,42,2); Gives a 4-dimensional array of unequal lengths.
function multiDimArrayInit(dimensions, leafValue) {
if (!dimensions.length) {
return leafValue;
}
var arr = [];
var subDimensions = dimensions.slice(1);
for (var i = 0; i < dimensions[0]; i++) {
arr.push(multiDimArrayInit(subDimensions, leafValue));
}
return arr;
}
console.log(multiDimArrayInit([2,8], "hi")); // counting the nested "hi"'s yields 16 of them
demo http://jsfiddle.net/WPrs3/
Here is my take on the problem: nArray utility function
function nArray() {
var arr = new Array();
var args = Array.prototype.slice.call(arguments, 1);
for(var i=0;i<arguments[0];i++) {
arr[i] = (arguments.length > 1 && nArray.apply(this, args)) || undefined;
}
return arr;
}
Usage example:
var arr = nArray(3, 3, 3);
Results in 3x3x3 array of undefined values.
Running code with some tests also available as a Fiddle here: http://jsfiddle.net/EqT3r/7/
The more dimension you have, the more you have interest in using one single flat array and a getter /setter function for your array.
Because for a [d1 X d2 X d3 X .. X dn] you'll be creating d2*d3*...*dn arrays instead of one, and when accessing, you'll make n indirection instead of 1.
The interface would look like :
var myNArray = new NArray(10,20,10);
var oneValue = myNArray.get(5,8,3);
myNArray.set(8,3,2, 'the value of (8,3,2)');
the implementation depends on your preference for a fixed-size
n-dimensionnal array or an array able to push/pop and the like.
A more succinct version of #chris code:
function multiDim (dims, leaf) {
dims = Array.isArray (dims) ? dims.slice () : [dims];
return Array.apply (null, Array (dims.shift ())).map (function (v, i) {
return dims.length
? multiDim (dims, typeof leaf == 'string' ? leaf.replace ('%i', i + ' %i') : leaf)
: typeof leaf == 'string' ? leaf.replace ('%i', i) : leaf;
});
}
console.log (JSON.stringify (multiDim ([2,2], "hi %i"), null, ' '));
Produces :
[
[
"hi 0 0",
"hi 0 1"
],
[
"hi 1 0",
"hi 1 1"
]
]
In this version you can pass the first argument as a number for single dimension array.
Including %i in the leaf value will provide index values in the leaf values.
Play with it at : http://jsfiddle.net/jstoolsmith/r3eMR/
Very simple function, generate an array with any number of dimensions. Specify length of each dimension and the content which for me is '' usually
function arrayGen(content,dims,dim1Len,dim2Len,dim3Len...) {
var args = arguments;
function loop(dim) {
var array = [];
for (var a = 0; a < args[dim + 1]; a++) {
if (dims > dim) {
array[a] = loop(dim + 1);
} else if (dims == dim) {
array[a] = content;
}
}
return array;
}
var thisArray = loop(1);
return thisArray;
};
I use this function very often, it saves a lot of time
This is probably a really basic question, but either there is no answer on the web or I'm not using the correct terminology. I want to store two separate variables (A and B) into 1 master variable, so that master = A then B.
So if A = 3, B = 8, master would equal 38. Anyone know how to do this in JavaScript? I'm not a programmer but here is my attempt.
var A = 1;
var B = 5;
var master = A, B;
document.write(master);
You seem to be requesting string concatenation. If you want an array, use one of the other answers. Otherwise: var master = A.toString() + B.toString(); See this JSFiddle.
Use an array:
var A = 1,
B = 5;
var master = [A, B];
master[0]; // 1
master[1]; // 5
Both objects and arrays are OK, as has been suggested. I'll just throw in another suggestion - an encapsulation ;)
function Master(a, b) {
this.first = a;
this.second = b;
this.both = function() {
return a + '' + b;
}
}
And to use it
var a = 3;
var b = 8;
var m = new Master(a, b);
alert(m.first); // 3
alert(m.second); // 8
alert(m.both()); // 38 (mind the parentheses, this is a function call!)
I know you said you're new, so I probably shouldn't being throwing arrays on you. However, for the others...
If you plan to get more dynamic than a few variables, you might want to invest in arrays.Put them into an array, then loop through the array printing them out as a string into a variable.
var myArray = new Array();
myArray.push(3);
myArray.push(8);
var myString = "";
for(var a = 0; a < myArray.length; a++)
{
myString += myArray[a].toString();
}
let 1st_new = [ [ 123, 'jack', 'white', 'tehran' ];
let 2nd_new= [ 456, 'roz', 'black', 'theran' ] ];
let 1st_list.push("1");
let 2st_list.push("2");
console.log(1st_new);
console.log(2nd_new);
#or you could make vairables of thge lists and put it inside a "var master" and print that out.
>>> def clockwise(r):
... return list(r[0]) + clockwise(list(reversed(zip(*r[1:])))) if r else []
...
>>> a = [
... [ 1, 2, 3],
... [ 5, 6, 7],
... [ 9, 10, 11]]
>>> clockwise(a)
[1, 2, 3, 7, 11, 10, 9, 5, 6]
I'm trying to change the function clockwise into Javascript but can't seem to get it to work.
I've created some methods with similar functions:
function zip(masterArray){//zips 2 arrays
var innerLoop = masterArray.length; //inner loop
var outerLoop = 0;
//get length of shortest
for (var i = 0; i<masterArray.length;i++){
var a = masterArray[i].length;
if (outerLoop==0){outerLoop = a;}else if(a < outerLoop){outerLoop = a;}
}
var newOuterArray = new Array(outerLoop);
for (var x = 0; x<outerLoop;x++){
var newInnerArray = new Array(innerLoop);
for (var y = 0; y<innerLoop;y++){
newInnerArray[y] = masterArray[y][x];
}
newOuterArray[x] = newInnerArray;
}
return newOuterArray;
}
function reversed(arr){
var newArray = new Array(arr.length);
var n = 0;
for(var i=arr.length-1; i>=0; i--){
newArray[n++] = arr[i];
}
return newArray;
}
function clockwise(r){
if(r.length>0){
var a = reversed(zip(r.slice(1)));
a.splice(0,0,r[0]);
return clockwise(a);
}else{
return [];
}
}
Here's my progress. I'm stuck at the last part: clockwise error in firebug is too much recursion.
I think the problem lies in the use of splice. Try something like this instead...
function clockwise(r){
if(r.length>0){
var remaining = r.slice(1)
var a = reversed(zip(remaining));
return r[0].concat(clockwise(a));
} else {
return [];
}
}
I think you want the recursive call to clockwise() to be before you prepend r[0] otherwise you never get down to an empty string.
I don't follow what the algorithm is trying to do, but the Javascript version of clockwise looks like it can only ever return []. There are two return paths. One calls clockwise, the other returns [] so the only way out of that function is to return []. That's not how your python version works.
I haven't looked at reversed and zip, but there is a logic difference in the javascript version of clockwise. In the javascript version, you remove the first item in the array, then reverse and zip, then put the first item back on the array and call clockwise on the whole thing. In the Python version, you remvoe the first item in the array, call clocks and reverse on only the item without the first version, then add the first one back on afterwards. Very different logic. The Python version is much more likely to end.
I haven't looked at the other functions reverse and zip, but this looks like a more faithful javascript version of clockwise:
function clockwise(r) {
if (r.length > 0) {
var a = clockwise(reversed(zip(r.slice(1)))); // call clockwise on array starting at index 1
a.splice(0,0,r[0]); // put first value in original array back onto the beginning of the result
return (a); // return new array
} else {
return [];
}
}