ReactJS tutorial code ported ES6 Code not working - javascript

In ReactJS tutorial has a tutorial on building a tic tac toe game with React. There's this function that checks to see if a winning move is made.
function calculateWinner(squares) {
const lines = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6],
];
for (let i = 0; i < lines.length; i++) {
const [a, b, c] = lines[i];
if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
return squares[a];
}
}
return null;
}
it works but the for loop could be improved to use for x in lines like so
function calculateWinner(squares) {
const lines = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6],
];
for (let line in lines) {
const [a, b, c] = line;
if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
return squares[a];
}
}
return null;
}
but when I tried that it didn't find a winning so I resorted to the older code.
I'm not sure why though the second edit failed.

function calculateWinner(squares) {
const lines = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]];
for (let line in lines) {
console.log(line);
const [a, b, c] = line;
if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
return squares[a];
}
}
return null;
}
Run this code. Your line variable is index of array, not inner array (e.g. [0, 1, 2]).
EDIT:
As kristaps mentioned in comment proper solution is let line of lines (of instead of in).

here in your first code you are using for loop which can excess 2d array in proper way
example below program will produce out put like
[
0,
1,
2
]
const lines = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6],
];
for (let i = 0; i < lines.length; i++) {
const [a, b, c] = lines[i];
console.log(lines[i]);
}
and also for each loop is use for excess each element at a time for example below program will produce output like
1
2
3
as it
const lines = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6],
];
for (let line in lines) {
const [a, b, c] = line;
console.log(line)
}
i think you can understand what happened here

Related

2d array manipulation in javascript

I have a 2d array in the following format:
export const dataBubble = [
[0, 0, 0],
[0, 1, 0],
[0, 2, 0],
[0, 3, 0],
[0, 4, 0],
[0, 5, 0],
[0, 6, 0],
[0, 7, 0],
[0, 8, 0],
[0, 9, 0],
[0, 10, 0],
[1, 0, 6],
[1, 1, 8],
[1, 2, 5],
[1, 3, 6],
[1, 4, 1],
[1, 5, 4],
[1, 6, 5],
[1, 7, 5],
[1, 8, 4],
[1, 9, 3],
[1, 10, 9],
[2, 0, 5],
[2, 1, 5],
[2, 2, 5],
[2, 3, 6],
[2, 4, 8],
[2, 5, 7],
[2, 6, 8],
[2, 7, 5],
[2, 8, 4],
[2, 9, 2],
[2, 10, 8],
[3, 0, 9],
[3, 1, 5],
[3, 2, 9],
[3, 3, 8],
[3, 4, 5],
[3, 5, 4],
[3, 6, 2],
[3, 7, 5],
[3, 8, 7],
[3, 9, 6],
[3, 10, 3],
[4, 0, 7],
[4, 1, 3],
[4, 2, 9],
[4, 3, 5],
[4, 4, 11],
[4, 5, 6],
[4, 6, 7],
[4, 7, 6],
[4, 8, 4],
[4, 9, 4],
[4, 10, 5],
[5, 0, 1],
[5, 1, 3],
[5, 2, 6],
[5, 3, 8],
[5, 4, 5],
[5, 5, 5],
[5, 6, 4],
[5, 7, 8],
[5, 8, 9],
[5, 9, 2],
[5, 10, 4],
[6, 0, 2],
[6, 1, 1],
[6, 2, 0],
[6, 3, 3],
[6, 4, 8],
[6, 5, 5],
[6, 6, 6],
[6, 7, 2],
[6, 8, 5],
[6, 9, 6],
[6, 10, 4],
[7, 0, 1],
[7, 1, 0],
[7, 2, 5],
[7, 3, 0],
[7, 4, 5],
[7, 5, 8],
[7, 6, 9],
[7, 7, 0],
[7, 8, 7],
[7, 9, 8]
];
We need to reverse the array elements based on the first two elements of the inner array, such that the resultant array becomes:
[
[0,10,0],
[0,9,0],
[0,8,0],
[0,7,0],
[0,6,0],
[0,5,0],
[0,4,0],
[0,3,0],
[0,2,0],
[0,1,0],
[1,10,9],
[1,9,3],
[1,8,4],
[1,7,5],
.
.
.
.
.
.
.
.
.
[7,0,1]
I use this in a react js project, so is there anyway we can use the JS map function of an array to do it? If not what will be the optimal solution?
If your second value is guaranteed to be less than an amount (for example I assumed 1000 in this case) then you can do this:
dataBubble.sort((x, y) => (x[0] - y[0])*1000 + y[1] - x[1]);
Basically we sum them up, but give the first element a higher coefficient, thus making it the primary sorter.
Otherwise, you need to involve an if check:
dataBubble.sort((x, y) => {
if(x[0] == y[0]) {
return y[1] - x[1];
} else {
return x[0] - y[0];
}
});
If you return a negative value from the sort function, JS will put x before y. Otherwise it will put x after y.
If x[0] and y[0] are equal, we need to sort depending on x[1] and y[1]. y[1] - x[1] will be negative if x[1] is larger, therefore if x[1] is larger x will come before y.
If x[0] and y[0] are different we need to sort based on them. x[0] - y[0] will be negative if x[0] is smaller, therefore if x[0] is smaller, x will come before y.

Why is this code modifying my array without me telling it to? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
Hi guys so this function is part of a larger code I am writing but I isolated it to show my issue with it. So here is how it goes;
I declare an array called Movement as
var Movement =[
[1,8],[2,8],[3,8],[4,8],[5,8],[6,8],[7,8],[8,8],
[1,7],[2,7],[3,7],[4,7],[5,7],[6,7],[7,7],[8,7],
[1,6],[2,6],[3,6],[4,6],[5,6],[6,6],[7,6],[8,6],
[1,5],[2,5],[3,5],[4,5],[5,5],[6,5],[7,5],[8,5],
[1,4],[2,4],[3,4],[4,4],[5,4],[6,4],[7,4],[8,4],
[1,3],[2,3],[3,3],[4,3],[5,3],[6,3],[7,3],[8,3],
[1,2],[2,2],[3,2],[4,2],[5,2],[6,2],[7,2],[8,2],
[1,1],[2,1],[3,1],[4,1],[5,1],[6,1],[7,1],[8,1]
]
but when I enter console.log
console.log(Movement)
I get this
Movement =[
[0,8],[0,8],[0,8],[true,8],[true,8],[true,8],true,8],[true,8],
[false,7],[false,7],[3,7],[4,7],[5,7],[6,7],[7,7],[8,7],
[1,6],[2,6],[3,6],[4,6],[5,6],[6,6],[7,6],[8,6],
[1,5],[2,5],[3,5],[4,5],[5,5],[6,5],[7,5],[8,5],
[1,4],[2,4],[3,4],[4,4],[5,4],[6,4],[7,4],[8,4],
[1,3],[2,3],[3,3],[4,3],[5,3],[6,3],[7,3],[8,3],
[1,2],[2,2],[3,2],[4,2],[5,2],[6,2],[7,2],[8,2],
[1,1],[2,1],[3,1],[4,1],[5,1],[6,1],[7,1],[8,1]
]
Where is it getting all these true or false values? I don't deal with true or false at all in my code.
I run the array through a function that does not modify it NOR does the function return any true or false values so is there something I am missing?
JavaScript
let ChessMap = [
8, 3, 4, 7, 5, 4, 3, 8,
6, 6, 6, 6, 6, 6, 6, 6,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 8, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
60, 60, 60, 60, 60, 60, 60, 60,
80, 30, 40, 70, 50, 40, 30, 80,
];
var Movement = [
[1, 8],
[2, 8],
[3, 8],
[4, 8],
[5, 8],
[6, 8],
[7, 8],
[8, 8],
[1, 7],
[2, 7],
[3, 7],
[4, 7],
[5, 7],
[6, 7],
[7, 7],
[8, 7],
[1, 6],
[2, 6],
[3, 6],
[4, 6],
[5, 6],
[6, 6],
[7, 6],
[8, 6],
[1, 5],
[2, 5],
[3, 5],
[4, 5],
[5, 5],
[6, 5],
[7, 5],
[8, 5],
[1, 4],
[2, 4],
[3, 4],
[4, 4],
[5, 4],
[6, 4],
[7, 4],
[8, 4],
[1, 3],
[2, 3],
[3, 3],
[4, 3],
[5, 3],
[6, 3],
[7, 3],
[8, 3],
[1, 2],
[2, 2],
[3, 2],
[4, 2],
[5, 2],
[6, 2],
[7, 2],
[8, 2],
[1, 1],
[2, 1],
[3, 1],
[4, 1],
[5, 1],
[6, 1],
[7, 1],
[8, 1]
]
const Game = {
PlayerStatus: 1,
Grabstate: 0,
CheckU: 0,
CheckL: 0
}
CheckUpdate();
console.log(Movement)
function CheckUpdate() {
var uk = 3;
var lk = 59
for (var i = 0; i < 64; i++) {
inc = 0
if (ChessMap[i] === 70) {
lk = i
inc++;
}
if (ChessMap[i] === 7) {
uk = i
inc++
}
if (inc === 2) {
break;
}
}
var Matrix = []
Matrix = Movement;
var xu = Matrix[uk][0]
var yu = Matrix[uk][1]
var xl = Matrix[lk][0]
var yl = Matrix[lk][1]
//// upper king check list
//hotizontal uk left check
for (var j = uk; j >= 0; j--) {
var brker = 0;
if (brker === 1) {
break;
}
for (var n = xu; n >= 0; n--) {
if (Matrix[j][0] = n && Matrix[j][1] === yu) {
if (ChessMap[j] === 6 || ChessMap[j] === 8 || ChessMap[j] === 4 || ChessMap[j] === 3 || ChessMap[j] === 5) {
brker = 1;
}
if (ChessMap[j] === 80 || ChessMap[j] === 70) {
Game.CheckU = 1;
}
}
}
}
/// horizontal uk right check
for (var j = uk; j < uk + 7; j++) {
var brker = 0;
if (brker === 1) {
break;
}
for (var n = xu; n < 8; n++) {
if (Matrix[j][0] = n && Matrix[j][1] === yu) {
if (ChessMap[j] === 6 || ChessMap[j] === 8 || ChessMap[j] === 4 || ChessMap[j] === 3 || ChessMap[j] === 5) {
brker = 1;
}
if (ChessMap[j] === 80 || ChessMap[j] === 70) {
Game.CheckU = 1;
}
}
}
}
////////////////////////////////
console.log(Game.CheckU)
}
Your Movement array is being modified by this code:
if (Matrix[j][0]=n && Matrix[j][1]===yu)
You may have accidentally used an assignment operator (=) instead of an equality operator (===).

Complete missing sequence in array with zeros in javascript

I have the following array:
const arr = [
[5, 0.2],
[7, 0.6],
[8, 0.3],
[10, 0.4]
];
console.log(arr)
I need to ensure that the first element of the array is a sequence from 5 to 10:
[5, 6, 7, 8, 9, 10]
In the above example, these numbers within the sequence are missing:
[6, 9]
If they are missing, I need to include them with zeros:
const expectedResult = [
[5, 0.2],
[6, 0],
[7, 0.6],
[8, 0.3],
[9, 0],
[10, 0.4]
];
console.log(expectedResult)
Any ideas on how to achieve this?
You could map the missing parts with a closure over the actual index of the given array.
const
array = [[5, 0.2], [7, 0.6], [8, 0.3], [10, 0.4]],
result = Array.from(
{ length: 6 },
(i => (_, j) => array[i]?.[0] === j + 5 ? array[i++] : [j + 5, 0])(0)
);
console.log(result);

Splitting an array in equal parts

I am looking for a Javascript Algorithm to split an array into chunks, but avoiding any small left overs. For example:
_.chunk([1, 2, 3, 4, 5, 6, 7], 3) // [[1, 2, 3], [4, 5, 6], [7]]
But I want this:
_.chunk([1, 2, 3, 4, 5, 6, 7], 3) // [[1, 2, 3], [4, 5], [6, 7]]
_.chunk([1, 2, 3, 4, 5, 6, 7], 4) // [[1, 2, 3, 4], [5, 6, 7]]
_.chunk([1, 2, 3, 4, 5, 6, 7], 5) // [[1, 2, 3, 4], [5, 6, 7]]
_.chunk([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3) // [[1, 2, 3], [4, 5, 6], [7, 8], [9, 10]]
So basically the output is spread over several arrays with a maximum number of elements passed in as second argument.
You should recalculate the size, which might need to be smaller than given. Then calculate from where the size should be one less for the remaining chunks.
So you will have potentially two different chunk sizes (which differ by 1). For both you can call the original _.chunk:
function chunk(arr, size) {
const count = Math.ceil(arr.length / size);
size = Math.ceil(arr.length / count);
const i = arr.length-(size-1)*(arr.length%size && size-(arr.length%size));
return _.chunk(arr.slice(0, i), size).concat(
_.chunk(arr.slice(i), size-1));
}
for (let i = 1; i < 9; i++) {
console.log(i, JSON.stringify(chunk([1, 2, 3, 4, 5, 6, 7], i)));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.4/lodash.min.js"></script>
This is done without lodash, it generates an array of proper length then fills in the parts with slices of the input array. It's only a few lines of code, depending how you count.
The caveat is the slices are up to how the decimals round. For your last example, you want to chunk a 10-length array with a limit of 3 per chunk. Well, dividing it out, you'll get the output:
[ [1,2], [3,4,5], [6,7], [8,9,10] ]
and not what you wanted:
[ [1,2,3], [4,5,6], [7,8], [9,10] ]
For most applications I don't think it matters much. I'm using this to chunk large inputs to an API that is throttled.
function chunk(array, limit) {
const numChunks = Math.ceil(array.length / limit);
return Array.from(
{ length: numChunks },
(_, i) => array.slice(i * array.length / numChunks, (i + 1) * array.length / numChunks)
);
}
console.log(chunk([1, 2, 3, 4, 5, 6, 7], 3));
console.log(chunk([1, 2, 3, 4, 5, 6, 7], 4));
console.log(chunk([1, 2, 3, 4, 5, 6, 7], 5));
console.log(chunk([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3));
An alternative solution uses recursion to chunk the "leftover" array. This one meets your criteria.
function chunk(array, limit) {
if (array.length <= limit) return [array];
const perChunk = Math.ceil(array.length / Math.ceil(array.length / limit));
return [array.slice(0, perChunk)].concat(chunk(array.slice(perChunk), limit));
}
console.log(chunk([1, 2, 3, 4, 5, 6, 7], 3));
console.log(chunk([1, 2, 3, 4, 5, 6, 7], 4));
console.log(chunk([1, 2, 3, 4, 5, 6, 7], 5));
console.log(chunk([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3));

How do I make a list of all possible sums from 2 arrays?

For example let's say I have arrays
a = [1, 2, 3, 4, 5, 6] and b = a
And the output I expect would be:
1 + 1, 1 + 2, 1 + 3 ... 3 + 1, 3 + 2, 3 + 4 ... 6 + 3, 6 + 4, 6 + 5, 6 + 6
I would prefer to make this simple calculation in JS or Ruby, but I don't mind answer in any other language. Can anyone provide me any direction?
In Ruby:
a.product(b).map {|p| p.reduce(:+) }.uniq
a = [1, 2, 3, 4, 5, 6]
b = [1, 4, -1, 7, 9]
a.product(b).map { |a,b| a+b }.uniq
#=> [2, 5, 0, 8, 10, 3, 6, 1, 9, 11, 4, 7, 12, 13, 14, 15]
The steps:
c = a.product(b)
#=> [[1, 1], [1, 4], [1, -1], [1, 7], [1, 9],
# [2, 1], [2, 4], [2, -1], [2, 7], [2, 9],
# [3, 1], [3, 4], [3, -1], [3, 7], [3, 9],
# [4, 1], [4, 4], [4, -1], [4, 7], [4, 9],
# [5, 1], [5, 4], [5, -1], [5, 7], [5, 9],
# [6, 1], [6, 4], [6, -1], [6, 7], [6, 9]]
d = c.map { |a,b| a+b }
#=> [2, 5, 0, 8, 10,
# 3, 6, 1, 9, 11,
# 4, 7, 2, 10, 12,
# 5, 8, 3, 11, 13,
# 6, 9, 4, 12, 14,
# 7, 10, 5, 13, 15]
d.uniq
#=> [2, 5, 0, 8, 10, 3, 6, 1, 9, 11, 4, 7, 12, 13, 14, 15]
In javascript, get unique sums using Set
var a = [1, 2, 3, 4, 5, 6];
var r = new Set();
a.forEach(x => a.forEach(y => r.add(x + y)))
document.write('<pre>' + Array.from(r) + '</pre>');
You can use Array.prototype.forEach() for the iteration over the arrays.
The forEach() method executes a provided function once per array element.
The result is without repeat.
function xSums(array) {
var r = [],
o = {};
array.forEach(function (a) {
array.forEach(function (b) {
if (!o[a + b]) {
r.push(b + a);
o[a + b] = true;
}
});
});
return r;
}
document.write('<pre>' + JSON.stringify(xSums([1, 2, 3, 4, 5]), 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(xSums([3, 7, 42]), 0, 4) + '</pre>');
I would do something like this:
a = [1, 2, 3, 4, 5, 6]
a.permutation(2).map { |x, y| x + y }
Try looping through both arrays, adding the first to the second, and storing the results in a third, eg;
var one = [1, 2, 3];
var two = [4, 5, 6];
var three = [];
for(var x = 0; x < one.length; ×++){
for(var y = 0; y < two.length; y++){
three.push(one[x] + two[y]);
}
}
This would result in three[0] = 1 + 4, three[1] = 1+ 5, three[2] =1+ 6, three[3] = 2 + 4, three[4] = 2+ 5 etc...

Categories