javascript array value is changing after it has been pushed - javascript

I am trying to debug the code below.
It is supposed to create a 2d-array, with all of the permutations of the input string.
It starts off great, and the initial string is pushed to the array, but after I run the reverse function in step 4, the value in strArr changes from having a length of 3 to a length of 2. basically like it is skipping the concat in the reverse function, but when I ran it in the debugger, z has a length of 3 after the concat, but then when the function returns it, the length becomes 2 again.
any help would be appreciated.
function permAlone(str) {
var perms = [];
var totalPerms = factorial(str.length);
var strCodes = converter(str);
var strArr = [];
strArr.push(strCodes);
// overall loop
for (var X = 0; X < totalPerms; X++) {
//step 1
var largestI = -1;
for (var i = 0; i < strCodes.length - 1; i++) {
if (strCodes[i] < strCodes[i + 1]) {
largestI = i;
}
}
//if none found break loop
if (largestI == -1) {
break;
}
//step 2
var largestJ = -1;
for (var j = 0; j < strCodes.length; j++) {
if (strCodes[largestI] < strCodes[j]) {
largestJ = j;
}
}
//step 3
swap(strCodes, largestI, largestJ);
//step 4
strCodes = reverse(strCodes, largestI);
//step 5 push to array
strArr.push(strCodes);
}
console.log(strArr);
return strArr;
}
function factorial(x) {
for (var i = x - 1; i > 0; i--) {
x *= i;
}
return x;
}
function converter(x) {
var temp = [];
for (var i = 0; i < x.length; i++) {
temp.push(x.charCodeAt(i));
}
return temp;
}
function swap(a, i, j) {
var temp = a[i];
a[i] = a[j];
a[j] = temp;
}
function reverse(z, a) {
var endArr = z.splice(a+1);
endArr.reverse();
z = z.concat(endArr);
return z;
}
debugger;
permAlone('abc');

The reverse function returns a new array and does not manipulate the existing. You need to change your code to the following:
endArr = endArr.reverse();

It looks like it was an issue with having a shallow copy of the array.
I added z = z.slice(); to the reverse function and it fixed the issue.

Related

Make an array filled with numbers 1 to 10000 and then sum all of those numbers [duplicate]

This question already has answers here:
How to find the sum of an array of numbers
(59 answers)
Closed 6 years ago.
How can I turn this into a function that takes an array of any length and gives you the total?
var points = new Array(100);
for (var i = 0; i < 100; i++) {
points[i] = i + 1;
}
for(var i = 0; i < points.length; i++) {
console.log(points[i]);
}
You could do it in two loops, but you might as well just do one loop that does both tasks.
var array = [],
sum = 0;
for (var i = 1; i <= 10000; i++) {
array[i-1] = i;
sum += i;
}
If you want to generalize the task of finding the sum of an array, you can use a function like so:
function arraySum(array) {
var sum = 0;
for (var i = 0; i < array.length; i++)
sum += array[i];
return sum;
}
For those who can understand it though, using reduce is a best answer:
function arraySum(array) {
return array.reduce(function(a,b){return a+b}, 0);
}
You can do get the sum using the for loop itself simply by using a variable
var points = new Array(100),
sum = 0;
for (var i = 0; i < 100; i++) {
points[i] = i + 1;
}
for (var i = 0; i < points.length; i++) {
sum += points[i];
}
console.log(sum);
You can reduce these two operations using fill() and forEach() to generate the array and reduce() to get the sum
var points = new Array(10000); // create an array of size 10000
points.fill(1); // fill it with 1 which helps ti=o iterate using foreach
points.forEach(function(v, i) { // iterate the array, you can also use simple for loop here
points[i] = v + i; // update the value
});
var sum = points.reduce(function(a, b) { // find sum
return a + b;
});
console.log(sum);
Using for loop and reduce()
var points = []; // initialize an array
for (var i = 1; i <= 10000; i++) {
points.push(i);
}
var sum = points.reduce(function(a, b) { // find sum
return a + b;
});
console.log(sum);
Also you can do the addition and array creation in single for loop
var points = [], // initialize an array
sum = 0;
for (var i = 1; i <= 10000; i++) {
points.push(i); // pushing value to array
sum += i; // summation
}
console.log(sum, points);
var result = 0;
for(var i = 0; i < points.length; i++) {
result += points[i];
}
Function that takes an array of any length and returns the sum:
function sumArray(arrayToSum){
var result = 0;
for(var i = 0; i < arrayToSum.length; i++) {
result += points[i];
}
return result;
}
function arraysum(arraylength) {
var arraysum = 0;
var array1 = new Array();
for(i=1; i<=arraylength; i++) {
array1.push(i);
}
for(i = 0; i< array1.length; i++) {
arraysum += array1[i];
}
return arraysum;
}
Now when you call the function
arraysum(x)
pass the function some variable or integer for example 1, 15, or 10000.
A very elegant and compact solution is to use reduce. It accumulates the array values to reduce it to a single value by applying each value and a start value to a given function, whose return value is used as the start value for the next iteration:
function sum (a, b) {
return a + b;
}
console.log(points.reduce(sum, 0));
If you need to support older browser (e.g. IE 8) you can use a Polyfill.
If you need to create the list of numbers as well, you can create it with
var points = Array.apply(0, Array(10000))
.map(function (current, index) {
return index + 1;
});
It creates an array of 10000 elements and assigns each element it's index + 1.

Return Sorted Array Without Modifying Original Array

I'm having trouble with a function returning the original array as opposed to the sorted array. I tried to slice the array and return the sorted but it is not working. Any ideas on how to fix this?
function sortArr( comparator, array ){
var newArray = array.slice();
for(var i = 0; i < newArray.size; i++)
{
var min = i;
for(var x = i; x < newArray.size; x++)
{
if(comparator(newArray[min],newArray[x]) == true)
{
min = x;
}
}
var temp = newArray[i];
newArray[i] = newArray[min];
newArray[min] = temp;
}
return newArray;
}
I fixed the function:
function sortArr( comparator, array ){
/*your code here*/
var i, x;
var min;
var newArray = array.slice();
for(i = 0; i < newArray.length - 1; i++)
{
min = i;
for(x = i + 1; x < newArray.length; x++)
{
if(comparator(newArray[min],newArray[x]) == true)
{
min = x;
}
}
if(min != i){
var temp = newArray[i];
newArray[i] = newArray[min];
newArray[min] = temp;
}
}
return newArray;
}
Copy the array with slice and then use native sort:
function sortArr(comparator, array) {
return array.slice().sort(function(a,b) {
return comparator(a,b) * 2 - 1;
});
}
Your sorting algorithm doesn't look quite right. For a start the swapping of values should be inside the if statement. I would also advise to look at #Oriol's solution which is far more elegant.
function sortArr( comparator, array ){
var newArray = array.slice();
for(var i = 0; i < newArray.size; i++)
{
var min = i;
for(var x = i; x < newArray.size; x++)
{
if(comparator(newArray[min],newArray[x]) == true)
{
var temp = newArray[i];
newArray[i] = newArray[min];
newArray[min] = temp;
min = x;
}
}
}
return newArray;
}
{"index.js":"var globalArray = [5, 6, 3, 2, 9];
function nonMutatingSort(arr) {
let newArr = globalArray.slice();\n let emptyArr = [];
return emptyArr.concat(newArr).sort();
}
nonMutatingSort(globalArray);"}

How to write a function to double numbers and pass them as to an object

numbers = [1,2,3,4,5];
function doubling(number) {
number *= 2;
return number;
}
obj = {};
for (var i = 0; i < numbers.length; i++)
doubled = doubling(numbers[i]);
obj[numbers[i]] = doubled;
console.log(obj);
When I run my code, it prints '10' when what I want is for it to print {1:2, 2:4, 3:6, 4:8, 5:10}. Why does this happen?
function doubling(number) {
number *= 2;
return number;
}
obj = {};
// your problem was here you were missing the curly braces
// so it was only executing the first line in the loop
for (var i = 0; i < numbers.length; i++) {
doubled = doubling(numbers[i]);
obj[numbers[i]] = doubled;
}
console.log(obj);
Your original loop was basically this...
for (var i = 0; i < numbers.length; i++) {
doubled = doubling(numbers[i]);
}
obj[numbers[i]] = doubled; // numbers[i] is undefined so it
// sets obj[undefined] = 10
// (the value of double after the loop)
console.log(obj);

Prime numbers not printing in Javascript

I have the following code to find the prime numbers from 2 to 1000:
#!/usr/bin/env node
var primesarray = function(n) {
var nums = [];
for (var i = 0; i < n; i++) {
nums.push("1");
}
return nums;
};
var primes = function(arr) {
var i = 2;
var primes = [];
for (i = 2; i < arr.length - 1; i++) {
if (arr[i] === "1")
primes.push(i);
for (j = 2; Math.pow(i, j) < arr.length - 1; j++ ) {
arr[Math.pow(i,j)] = "0";
}
}
return primes;
};
// Print to console
var fmt = function(arr) {
return arr.join(",");
};
var k = 1000;
console.log("primes(" + k + ")");
console.log(fmt(primes(k)));
When I run the file, it just prints the first console.log line. I'm not seeing what's wrong here.
The function primes is written to expect an array, but you're passing it an integer.
Did you mean fmt(primes(primesarray(k)))?
(That does at least print a list of numbers, but I'm afraid many of them are not primes!)
You need to prime you array ;)
var arr = primesarray(k)
like this
var k = 1000;
var arr = primesarray(k)
console.log(primes(arr));
console.log(fmt(primes(arr)));
DEMO
Some actual solutions: http://www.codecademy.com/forum_questions/5033d10f77955e0002004142

Take an input single dimensional array [1,2,3,4] and output the product of the integers excluding the current index [24,12,8,6];

Guys I need your opinion; I've encountered this earlier during my interview, I just want to confirm I understood the question right and I got the answer correctly. Thank you. Please check the question and my answer below:
Take an input single dimensional array [1,2,3,4] and output the product of the integers excluding the current index [24,12,8,6];
//My answer
function calculate(values:Array):Array {
var resultArray:Array = new Array();
for(var i:int = 0; i < values.length; i++) {
var getVal1:Number = 1;
for(var k:int = 0; k <= values.length; k++) {
if(i != k) {
var getVal2:Number = values[k];
getVal1 *= getVal2;
}
}
resultArray.push(getVal1);
}
return resultArray;
}
Nested loops seems like a very messy way to go.
Assuming relatively up-to-date browser (IE 8 and below are out) or suitable shim:
var resultArray = sourceArray.map(function(val,ind,arr) {
arr = arr.slice(0); // create copy of array to work on here
arr.splice(ind,1); // remove current item from array
return arr.reduce(function(prev,curr) {return prev*curr;},1);
});
Array.prototype.map
Array.prototype.reduce
EDIT Here's another way that should be more efficient:
var product = sourceArray.reduce(function(prev,curr) {return prev*curr;},1);
var resultArray = sourceArray.map(function(val) {return product/val;});
Your solution gives the correct answer, but there is a much more efficient method to calculate the new array:
function calculate(values:Array):Array {
var resultArray:Array = new Array();
var product:int = 1;
for(var i:int = 0; i < values.length; i++) {
product *= values[i];
}
for(var i:int = 0; i < values.length; i++) {
resultArray.push(product / values[i]);
}
return resultArray;
}
This solution has O(n) execution time, while your code has O(n²) execution time.
That should work. You can do it easier and more efficiently by multiplying all items first:
function calculate(values) {
var prod = 1;
for (var i = 0; i < values.length; i++) prod *= values[i];
var result = [];
for (i = 0; i < values.length; i++) result.push(prod / values[i]);
return result;
}
I believe that my code below is very easy to read. And has no nested loops, but two consecutives. My answer would be:
function calculate(array){
var total = array.reduce(function(a, b){
return a * b;
});
return array.map(function(element){
return total / element;
});
}
Though I like #Kolink's short-and-efficient solution best, here's another way to solve the task - not using division but still being in O(n):
function calculate(values) {
var acc = 1,
l = values.length,
result = new Array(l);
for (var i=0; i<l; i++) {
result[i] = acc;
acc *= values[i];
}
acc = 1;
while(i--) {
result[i] *= acc;
acc *= values[i]
}
return result;
}
Or, the same thing but a little obfuscated*:
function calculate(values) {
var acc = 1,
i = 0,
l = values.length,
result = new Array(l);
if (l)
result[i] = 1;
while( ++i < l)
result[i] = acc *= values[i-1];
i -= acc = 1;
while (i--)
result[i] *= acc *= values[i+1];
return result;
}
*: I like shorthand operators!

Categories