I am trying to make tic tac toe game in vanilla javascript. If I use ! to flip the value of object boolean property , it is changed to what it is defined in global memory object (as soon as it is out of its execution context), however If I flip by using = equal sign, it stays same. aren't they both doing same thing(flipping value)?? Any explanation would be appreciated.
Here's my code.
// we need an object for storing the state of our game.
const game = {
xTurn: true,
xState: [],
oState: [],
winningStates: [
// Rows
['0', '1', '2'],
['3', '4', '5'],
['6', '7', '8'],
// Columns
['0', '3', '6'],
['1', '4', '7'],
['2', '5', '8'],
// Diagonal
['0', '4', '8'],
['2', '4', '6']
]
}
document.addEventListener('click',e=>{
const target = e.target;
console.log('initializing code')
const isCell = target.classList.contains('grid-cell')
const isDisabled = target.classList.contains('disabled');
if(isCell && !isDisabled){
const cellValue = target.dataset.value;
if(game.xTurn){
game.xState.push(cellValue)
}else{
game.oState.push(cellValue)
}
target.classList.add('disabled')
target.classList.add(game.xTurn ? 'x' : 'o')
// if(game.xTurn){
// target.classList.add('x')
// }else{
// target.classList.add('o')
// }
console.log(game.xTurn)
game.xTurn = !game.xTurn;
// game.xTurn = false;
console.log(game.xTurn)
}
})
Related
I want to parse this dictionary:
var data = {'Charlie':
{'keys':
{'a': '1',
'b':['1', '2', '3'],
'c': '3'},
},
'Derek':
{'keys':
{'a': '10',
'b': ['9', '8', '7'],
'c': '9'},
}
};
But I want "Charlie" and "Derek" to appear as li names instead of Dummy. Still - I can't since I don't see them in response. They disappear after parsing, leaving:
'keys':
{'a': '1',
'b':['1', '2', '3'],
'c': '3'}
and
'keys':
{'a': '10',
'b': ['9', '8', '7'],
'c': '9'},
The full code:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<div>
<h3>Div underneath</h3>
<ul id="main-ul">
</ul>
</div>
</body>
<script>
var data = {'Charlie':
{'keys':
{'a': '1',
'b':['1', '2', '3'],
'c': '3'},
},
'Derek':
{'keys':
{'a': '10',
'b': ['9', '8', '7'],
'c': '9'},
}
};
lay_out_tab_structure(data)
function lay_out_tab_structure(response) {
console.log("response in lay_out_tab is", response)
var ul = $('#main-ul');
for (const [key, value] of Object.entries(response)) {
var li = document.createElement('li')
var div = document.createElement('div')
li.append(div);
ul.append(li);
console.log("The key-value pair before passing is", (key, value))
create_row(li, (key, value))
}
};
function create_row(listItem, content) {
console.log("Content in create row is", content)
var mainDiv = $(listItem).children('div');
var name = $('<p class="css-big-letter machine-name">'+'<a style="color:inherit;">'+"Dummy"+'</a>'+'</p>');
var titleDiv = $('<div style="position:relative;margin-bottom:1%;"></div>');
titleDiv.append(name);
mainDiv.append(titleDiv);
var RowDiv = $('<div></div>');
$(mainDiv).append(RowDiv);
};
</script>
</html>
Can you help me?
I have already tried this solution and I couldn't get it working:
Object.entries() turning keys into arrays
Object.entries() will, as your code reflects, provide you with a list of 2-element arrays. Your code destructures each of those arrays into your key and value variables. All of that is fine.
However, when you want to pass both the key and the value to another function, you'll have to either pass each as a separate parameter, or else collect them back into a 2-element array. The statement
create_row(li, (key, value))
does not do either of those things. The expression (key, value) is a comma expression and will evaluate only to value, as you've found out. Thus, you could either change create_row() to accept a total of 3 parameters and pass key and value individually, or else group those two into a new array:
create_row(li, [key, value])
Either way will work. If you go with the array, then inside create_row() the key will be content[0] and the value will be content[1].
I have a text and want to summarize it , i want change this array :
Array 1
[
'CALX', '11.10', '21',
'01', '08', 'EGLD',
'USDT', 'LDFDFC', 'ZONE',
'238.5', '233', 'LEVERAGE',
'3', 'X', 'TARGET',
'1', '243.9', 'TARGET',
'2', '248', 'TARGET',
'3', '254', 'TARGET',
'4', '260', 'H',
'GD', 'S', 'AFCA'
]
to this :
Array 2
[
'CALX', '11.10', '21',
'01', '08', 'EGLDUSDTLDFDFCZONE',
'238.5', '233', 'LEVERAGE',
'3', 'XTARGET',
'1', '243.9', 'TARGET',
'2', '248', 'TARGET',
'3', '254', 'TARGET',
'4', '260', 'HGDSAFCA',
]
as you can see , I want all the letters to stick together until they reach a number,and each number should be in an element of the array
This is the code that can be used to convert text to an Array1
const input = 'CALX, [11.10.21 01:08] $EGLD/USDT #Ldfdfc zone : 238.5 - 233 "LEVERAGE" : 3x TARGET1 : 243.9 TARGET 2 : 248 TARGET 3 : 254 TARGET 4 : 260 h.gd.s afca. `~!##$%^&*()_-+=-/?><'
const text = text.toUpperCase().match(/[a-z]+|\d+(?:\.\d+)?/gi);
so how can i change the Array1 to Array2?
sorry for my English and thank you for your help.
Based on the initial string, to get the desired array as output you don't have to convert it to an array to process it again.
You can use a pattern similar like the one that you tried with an alternation | but instead of matching [a-z]+ you can capture 1 or more non digits using (\D+) in a group.
Then in the callback of replace, you can remove the unwanted characters if there is a match for the group 1. The unwanted characters are [\W_]+ or one more non word chars including the underscore.
If there is no group, you can return the match (the digits) between delimiters, where you can split on the delimiters afterwards to create the final array.
const input = 'CALX, [11.10.21 01:08] $EGLD/USDT #Ldfdfc zone : 238.5 - 233 "LEVERAGE" : 3x TARGET1 : 243.9 TARGET 2 : 248 TARGET 3 : 254 TARGET 4 : 260 h.gd.s afca. `~!##$%^&*()_-+=-/?><'
text = input
.toUpperCase()
.replace(/\d+(?:\.\d+)?|(\D+)/g,
(m, g1) => g1 ? g1.replace(/[\W_]+/g, '') : `#${m}#`
);
console.log(text.split(/#+/));
One of the solution could look like this:
let arr = [
'CALX', '11.10', '21',
'01', '08', 'EGLD',
'USDT', 'LDFDFC', 'ZONE',
'238.5', '233', 'LEVERAGE',
'3', 'X', 'TARGET',
'1', '243.9', 'TARGET',
'2', '248', 'TARGET',
'3', '254', 'TARGET',
'4', '260', 'H',
'GD', 'S', 'AFCA'
]
function handleArray(a) {
let result = [];
let stringItem = '';
a.forEach((el) => {
// If number then check if we have previous string and push
// it to the result.
// Also push number as next element
if (/\d/.test(el)) {
if (stringItem) {
result.push(stringItem);
// Clear string variable
stringItem = '';
}
result.push(el)
} else {
// Concat ongoing string, don't push to result
stringItem += el;
}
})
return result;
}
console.log(handleArray(arr))
I have an array of Javascript objects indexed by key values listed below, each key representing a Javascript object (this is just a console.log() of the key values in the array):
[ '532',
'789',
'1232',
'2346',
'3404',
'4991',
'5323',
'5378',
'8923',
'9876',
'23434',
'23549',
'24454',
'34234',
'45667',
'48983',
'67834',
'72342',
'82434',
'89829',
'98732',
'123404',
'143454',
'234345',
'345294',
'532234',
'532342',
'532345',
'532349',
'989898' ]
When I console.log() out this Javascript array it is "filled-in" with "NULL" values. For example the first key is 532, so when printing this array out first there are 531 "NULL" values printed and the then Javascript object with key 532 and so on for each key.
So my solution is to remove the null values by running this function below on the array:
teamData = teamData.filter(function (el) {
return el != null && el != "";
});
My Issue:. Once I run that filter function the array key values are reset to:
[ '0',
'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' ]
Question: Is there a way to filter out the null values between the array keys while still keeping the key values in the first array? Is there another way to structure this data so there won't be null values?
Problem is that you're trying to use an array index position as key. This won't work because arrays always have consecutive indexes starting from 0. So if you gonna have an element at index 532 then there necessarily will be 532 elements before it (0 to 531). If you remove those elements with filter the indexes will shift to the correct position, in your case from 0 o 29. In Javascript there is a native object for your use case, it is called Map, here you can read everything about it.
I want to execute int function based on specific times (in seconds) from the times array.
let times = [
//[type, startTime, endTime]
['A', '2', '5'],
['B', '7', '9'],
['C', '12', '15'],
];
function int(startTime, endTime){
console.log(startTime);
console.log(endTime);
};
So we should execute the int function in seconds 2 , 7 and 12 (the second element in the inner arrays)
Note: we should be able to pass arrays to times array and the code should still work.
I have no idea if this is possible and need a hand to find a solution.
I would do it like this. The code should explain itself but if you have any questions let me know.
let times = [
//[type, startTime, endTime]
['A', '2', '5'],
['B', '7', '9'],
['C', '12', '15'],
];
function int(startTime, endTime) {
console.log(startTime);
console.log(endTime);
};
times.forEach((elem)=> {
setTimeout(() => {
int(elem[1], elem[2]); // Call to function
}, elem[1] * 1000); // Conversion to seconds
});
I want to find out whether an Array is present in an JavaScript object.
Dummy example:
Given a Javascript Object containing an Array. and we dont know if there is an Array present in the Object.
var dummyObject = {
backgroundcolor: '#000',
color: '#fff',
arr: ['1','2','3','4','5','6']
};
Now I want to check if there is an array in this object and if there is print all the elements of that Array.
Currently I am onto one solution i.e. to Iterate each key and check each if them if there is an array in it using Array.isArray(key).
Any help would be great.
Using Array.isArray is the correct method for going about this. Iterating through each key is pretty simple too. Then once you find the item, just log it to the console:
var dummyObject = {
backgroundcolor: '#000',
color: '#fff',
arr: ['1', '2', '3', '4', '5', '6']
};
const arr = Object.entries(dummyObject).find(([, v]) => Array.isArray(v));
if (arr) console.log(arr[1]);
.as-console-wrapper { max-height: 100% !important; top: auto; }
You can use some with Object.values if you just want a Boolean determining whether an array exists inside an object:
var dummyObject = {
backgroundcolor: '#000',
color: '#fff',
arr: ['1', '2', '3', '4', '5', '6']
};
const arrInObj = Object.values(dummyObject).some(e => Array.isArray(e));
console.log(arrInObj);
And if you want, you can avoid using Array.isArray and check for the existence of the map property instead (à la code golf):
var dummyObject = {
backgroundcolor: '#000',
color: '#fff',
arr: ['1', '2', '3', '4', '5', '6']
};
const arrInObj = Object.values(dummyObject).some(({ map }) => map);
console.log(arrInObj);
if (dummyObject.arr){
console.log('arr is present')
}else{
console.log('arr is not present')
}