Original code in JS:
// applying crossover
for (let i = cxpoint1; i < cxpoint2; i++) {
let temp1 = ind1[i]
let temp2 = ind2[i]
ind1[i] = temp2
ind1[p1[temp2]] = temp1
ind2[i] = temp1
ind2[p2[temp1]] = temp2
return [ind1, ind2]
New to JS and wondering what is happening on this line:
ind1[p1[temp2]] = temp1
Trying to understand so I can make an equivalent function in Python.
I understand the assignment, however obviously in Python you cannot use double brackets as shown on the line above. If someone could tell me the concept, I should be able to apply it to my situation.
Thanks in advance.
To fully understand the code one would need to know how the arrays p1 and p2 look like, but I assume they are integer-arrays. You select an integer from that array in the inner statement that then is the index for the outer statement.
It works exactly the same in python:
ind1 = [1, 2, 3, 4, 5]
p1 = [3, 1, 2]
print(ind1[p1[0]])
# -> 4
In this example the inner statement resolves to 3 (first element in the p1-list) and the outer statement then resolves to 4 (fourth element in the ind1-list.
There's nothing magical going on here.
ind1[p1[temp2]]
p1[temp2] resolves to some value, let's call it a. So the expression then becomes ind1[a].
Related
I am supposed to rotate an array of integers clockwise in JS.
Here is my code for it:
function rotateArray(N, NArray)
{
//write your Logic here:
for(j=0;j<2;j++){
var temp=NArray[N-1];
for(i=0;i<N-1;i++){
NArray[i+1]=NArray[i];
}
NArray[0]=temp;
}
return NArray;
}
// INPUT [uncomment & modify if required]
var N = gets();
var NArray = new Array(N);
var temp = gets();
NArray = temp.split(' ').map(function(item) { return parseInt(item, 10);});
// OUTPUT [uncomment & modify if required]
console.log(rotateArray(N, NArray));
The code accepts an integer N which is the length of the array. The input is as follows:
4
1 2 3 4
The correct answer for this case is supposed to be
4 1 2 3
But my code returns
4 1 1 1
I cannot find where my code is going wrong. Please help me out.
All you need to do is move one item from the end of the array to the beginning. This is very simple to accomplish with .pop() (removes an item from the end of an array), then declare a new array with that element as the first:
function rotateArray(N, NArray) {
const lastItem = NArray.pop();
return [lastItem, ...NArray];
}
console.log(rotateArray(1, [1, 2, 3, 4]));
Doing anything else, like using nested loops, will make things more unnecessarily complicated (and buggy) than they need to be.
If you don't want to use spread syntax, you can use concat instead, to join the lastItem with the NArray:
function rotateArray(N, NArray) {
const lastItem = NArray.pop();
return [lastItem].concat(NArray);
}
console.log(rotateArray(1, [1, 2, 3, 4]));
If you aren't allowed to use .pop, then look up the last element of the array by accessing the array's [length - 1] property, and take all elements before the last element with .slice (which creates a sub portion of the array from two indicies - here, from indicies 0 to the next-to-last element):
function rotateArray(N, NArray) {
const lastItem = NArray[NArray.length - 1];
const firstItems = NArray.slice(0, NArray.length - 1);
return [lastItem].concat(firstItems);
}
console.log(rotateArray(1, [1, 2, 3, 4]));
function rotate(array,n){
Math.abs(n)>array.length?n=n%array.length:n;
if(n<0){
n=Math.abs(n)
return array.slice(n,array.length).concat(array.slice(0,n));
}else{
return array.slice(n-1,array.length).concat(array.slice(0,n-1));
}
}
console.log(rotate([1, 2, 3, 4, 5],-3));
The answer by #CertainPerformance is great but there's a simpler way to achieve this. Just combine pop with unshift.
let a = [1,2,3,4];
a?.length && a.unshift(a.pop());
console.log(a);
You need to check the length first so you don't end up with [undefined] if you start with an empty array.
I have been asked with this question in one of my recent interviews.
For a given array, say, Arr[2,2,4,3,4,2,3,2,4]
write a javascript function to return an object with the count of each number in the above array, like
countArr={2:4,3:2,4:3}
After a lot of google I have ended up with the below code which is returning the correct data.
var uniqueCount = [2, 2, 4, 3, 4, 2, 3, 2];
var count = {};
uniqueCount.forEach(function(i) {
count[i] = (count[i] || 0) + 1;
});
console.log(count);
As I said this works fine! Output: {2: 4, 3: 2, 4: 2}
Well, a code without proper understanding of whats happening in back ground means nothing for a developer :)
Can anyone please help me out to understand how this actually work?
The main work of creating an object with each of the unique array element's count
is happening in the following block:
uniqueCount.forEach(function(i) {
count[i] = (count[i] || 0) + 1;
});
Here we are iterating over each of the elements in the array like we do in a 'for loop'. I hope you are familiar with the working of a 'for loop'. Then, we are passing each element of the array in a function.
count[i] = (count[i] || 0) +1;
can be written as:
if(count[i]) {
count[i] = count[i] + 1;
} else {
count[i] = 1;
}
Hope that helps you to understand the code.
Ok, it's actually simple. Let's go step by step.
var count = {};
Declares a JS object. It's basically a key-value store. You can access the value of a key by writing count[key]. Then store or retrieve the value.
Consider this simple example:
var count = {}
count['ok'] = 3
console.log(count)
It outputs { ok: 3 }
Now replace 'ok' with a number, and you get the structure of the rest of the code : keys are added to the object for each number found in the array, or are incremented when they exists.
Let's continue with the code.
uniqueCount.forEach(function(i) {
// code here is called for each entry in the uniqueCount array, i being the current value.
});
And finally, the magic happens here:
count[i] = (count[i] || 0) + 1;
From left to right, it reads: assign to the i property of the count object a value that is it's current value or 0 if there is none, then add 1. So if the i number was already seen it takes the previous value and adds 1; if it wasn't seen, it takes 0 and adds one.
So when you console.log(count) you get the values for all of those properties.
The code uses an object as a map from number values to integer counts of their frequency.
1. var uniqueCount = [2, 2, 4, 3, 4, 2, 3, 2];
2. var count = {};
3. uniqueCount.forEach(function(i) {
4. count[i] = (count[i] || 0) + 1;
5. });
6. console.log(count);
Line 1: Declare variable uniqueCount and assign to it a new array of numbers.
Line 2: Declare variable count and assign to it a new, empty object.
Line 3: Run an anonymous function once for each number in uniqueCount.
Line 4: Assign to a property on count, named with the current number in the array: one plus the existing value of the property, or if the property does not already exist, zero.
Line 6: Print the final state of count.
The code would be clearer if the variable i in the anonymous function was named n (or something) because i (yes, I know it means "integer" here) usually means "index", and here, it is not the index.
Note that in JavaScript simply assigning a value to a property on an object will create that property if it does not already exist.
I assume there is only one line that confused you:
count[i] = (count[i] || 0) + 1; means
If there is already a count for digit i set count[i] to that value, otherwise set it to 0 (initialise it) then add 1 to whatever is in count[i] now
Can be rewritten like this to make it more understandable - note I changed the variable, array and object names
var array = [2, 2, 4, 3, 4, 2, 3, 2];
var uniqueCount = {};
array.forEach(function(digit) {
if (uniqueCount[digit]) uniqueCount[digit]++; // if counter for the digit exist, add 1
else uniqueCount[digit] = 1; // else initialise it to 1
});
console.log(uniqueCount);
I am trying to create this memory game in ReactJS and I have made an array in which I add 4 random numbers. Now everytime I press play game I need to fill the array with 4 random numbers 0 to 3 but I keep getting random commas that come out of nowhere in the array. I am quite new to React so any help is appreciated.
I have tried different methods of filling up the array but the commas still appear. P.S: keepArray was initialized just before the for loop.
for (let i = 0; i < 4; i++) {
let rand = Math.floor(Math.random() * 4)
keepArray = [...keepArray + rand]
console.log(keepArray)
}
Solution:
Replace:
keepArray = [...keepArray + rand]
with:
keepArray = [...keepArray, rand]
Explanation:
The spread operator (...) is literally "spreading" your array, that's why you need commas. The example bellow may help to visualize it:
// Let's start with a simple array:
var myArray = [1, 2, 3];
// Now, we add another element to it using spread:
var updatedArray = [...myArray, 4];
// Here, ...myArray is translated to [1, 2, 3]
// That means that the above could be read as:
var updatedArray = [1, 2, 3, 4];
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
For an extra explanation about the "+" behavior, see Pavan Bahuguni answer.
The above answer does fix the problem, but the real reason for the behaviour is as follows.
The + operator is overloaded to serve the purposes of both number addition and string concatenation. When + receives an object (including array in your case) for either operand, it first calls the ToPrimitive abstract operation on the value, which then calls the [[DefaultValue]] algorithm with a context hint of number. Which intern calls toString method on the array.
var val = [1,2,3] + 1;
console.log(val); // "1,2,31"
And then you are trying to spread that string in an array like so,
var arr = [...val];
console.log(arr); // ["1", ",", "2", ",", "3", "1"]
this is the actual reason why you are seeing those commas.
I am trying to work through this problem and I am having trouble understanding why the function reverseArrayInPlace isn't doing what I want it to. The console.log in the function will return a reversed array, but when I return the same thing, I don't get the reversed array.
I am a beginner so please dumb down the answers alot. Thanks
function reverseArray(array){
var x = [];
for (i=array.length - 1; i>=0; i--){
x.push(array[i]);
}
return x;
}
function reverseArrayInPlace(array){
console.log(reverseArray(array));
return reverseArray(array);
}
//console.log(reverseArray(["A", "B", "C"]));
// → ["C", "B", "A"];
var arrayValue = [1, 2, 3, 4, 5];
reverseArrayInPlace(arrayValue);
console.log(arrayValue);
// → [5, 4, 3, 2, 1]
Edit: Thanks for the replies. Can I get some feedback on this function:
function reverseArrayInPlace(array){
for (i=1; i<array.length; i++){
var x = array[i];
array.splice(i,1);
array.unshift(x);
}
return array;
}
It seems to be working for me. Can you see anything wrong with it?
You aren't reversing the array in place
In the function you are creating a new array and then adding the elements in reverse order
in the first line of your function you create a new variable
var x = [];
Unless you want to change your implementation to handle both cases in reverseArray you need to implement a different solution in the reverseArrayInPlace function
You will need to
Determine the element to swap from the front
Determine the element to swap from the back
Know when you have reached the middle of the array and stop
You can optionally return the array if you would like to, but since the change is made in place you shouldn't need to
The reverseArrayInPlace() function isn't actually working in place. It is calling reverseArray() which is creating a new array to store the elements. As such, it needs to be returning this value.
why not just...
var arrayValue = [1, 2, 3, 4, 5];
arrayValue = arrayValue.reverse();
console.log(arrayValue);
edit: nvm i see you are workign through a tutorial. imo this is the most elegant way though.
I need help with the five.myArraysCombined property.
I need it to equal just 1 array (which it currently does in fiddle) and I need it to NOT add any numbers together. (so each number in the array shouldn't be over 20, just like no number in the other arrays are over 20)
http://jsfiddle.net/Dc6HN/1/
For example, if the five arrays are like this
five.myArray1 = [7,2,9,19,3];
five.myArray2 = [6,18,8,1,7];
five.myArray3 = [7,19,4,8,2];
five.myArray4 = [11,9,1,14,5];
five.myArray5 = [3,18,8,9,2];
then the all those arrays combined should be like this
five.myArraysCombined = [7,2,9,19,3,6,18,8,1,7,7,19,4,8,2,11,9,1,14,5,3,18,8,9,2];
Relevant code :
function theNumberClass() {
this.myArray = [[],[],[],[],[]];
this.myArraysCombined = [];
}
var five = new theNumberClass();
function prePickNumbers(objName, theNum, theSumNum, theMaxNum, theMinNum) {
var zzz = [];
for (var x = 0; x < theNum; x += 1) {
pickNumbers(objName.myArray[x], theNum, theSumNum, theMaxNum, theMinNum);
zzz += objName.myArray[x];
}
objName.myArraysCombined.push(zzz);
}
prePickNumbers(five, 5, 40, 20, 1);
My latest attempt was with var zzz and then pushing it to the property, but when I do that it adds up the numbers in the array at times, which is not what I need.
I've also tried several attempts using the .concat(), but it seems to turn it into a string and sometimes also adds up the numbers.
Suppose you have those arrays :
var a = [1, 2, 3]
var b = [4, 5, 6]
var c = [8]
Then you can get a merge of all those with
var all = [].concat.apply([],[a,b,c])
or with
var all = [a,b,c].reduce(function(merged, arr){ return merged.concat(arr) })
In both cases you get
[1, 2, 3, 4, 5, 6, 8]
The first solution is simpler, the second one is more extensible if you want, for example, to remove duplicate or do any kind of filtering/transformation.
I would guess that the issue is the "+=" operator. This operator is used to sum values, not add new elements to an array. Take the following line of code as an example:
zzz += objName.myArray[x];
What I am guessing is that "myArray[x]" is getting added to the value of zzz instead of getting appended to the end of the array. When adding elements to an array in javascript, push is the best option. A better way to write this line is:
zzz.push(objName.myArray[x]);
The question was a bit confusing so I'm not sure if this is what you are looking for but hopefully it will help anyways.
five.reduce(function(o,n){return o.concat(n)},[])
This will reduce the array to a single value, in this case an array of numbers. You can look up Array.reduce() on MDN for more info.
After many hours trying all suggestions left on this thread and another one, and trying multiple other things. I think I finally found a very simple way to do this. And it's the only way I tried that works 100% like I want.
http://jsfiddle.net/Dc6HN/2/
function prePickNumbers(objName, theNum, theSumNum, theMaxNum, theMinNum) {
for (var x = 0; x < theNum; x += 1) {
pickNumbers(objName.myArray[x], theNum, theSumNum, theMaxNum, theMinNum);
objName.myArraysCombined.push(objName.myArray[x]);
}
objName.myArraysCombined = objName.myArraysCombined.toString();
objName.myArraysCombined = objName.myArraysCombined.split(',');
}