Combine and sum the values in multiple arrays - javascript

All the relevant code is provided here http://jsfiddle.net/DuWGj/ , as well as print(appendTo) statements.
To keep it short, I'm making 4 arrays. Each array has 4 numbers. Then I create a new array that has all those 4 arrays numbers inside of it, so it's one array.
For example the end result is
four.myArraysCombined = [5,3,20,12,3,4,18,11,12,5,8,2,1,9,10,6];
However, when I try
four.myArraysCombined[3] , it says it's undefined.
so obviously when I do the following it doesn't work
var total = 0;
for (var x = 0; x < 16; x++) {
total += four.myArraysCombined[x]);
}
I'm looking to be able to add all those numbers together with a for loop. I've tried several things but it keeps giving me undefined or NaN.

What is happening
After running:
prePickNumbers(four, 4, 40, 20, 1);
...the value of four.myArraysCombined is:
[[[2, 17, 20, 1], [7, 2, 20, 11], [7, 14, 3, 16], [12, 17, 3, 8]]]
In other words, it is not the result that you claim it is. You should verify that you have the result that you think you do at each step of the process, before moving on. As it stands, you do not have a flattened array. You need to fix that first and then move on to iterating and summing.
Why this is happening
The reason for the final structure starts at the following line in prePickNumbers:
tempMyArraysCombined.push(objName.myArray[x]);
You're pushing an array into another array each time, so the result after the loop is an array of arrays. But, then, you push that result into another array:
objName.myArraysCombined.push(tempMyArraysCombined);
So the final result is actually an array containing an array of arrays (notice the extra set of brackets in the output above). The problem is that you're pushing an entire array into your output at each step in the process, which is creating a nested mess. You should be pushing elements of each array, not the arrays themselves.
How to fix it
Here is one possible solution. Replace prePickNumbers with the following function:
function prePickNumbers(objName, theNum, theSumNum, theMaxNum, theMinNum) {
var tempMyArraysCombined = [];
for (var x = 0; x < theNum; x += 1) {
pickNumbers(objName.myArray[x], theNum, theSumNum, theMaxNum, theMinNum);
for (var j = 0; j < objName.myArray[x].length; j++) {
objName.myArraysCombined.push(objName.myArray[x][j]);
}
}
}

You may want to try
total += four.myArraysCombined[0][x]

I extract this from you fiddle:
function prePickNumbers(objName, theNum, theSumNum, theMaxNum, theMinNum) {
var tempMyArraysCombined = [];
for (var x = 0; x < theNum; x += 1) {
pickNumbers(objName.myArray[x], theNum, theSumNum, theMaxNum, theMinNum);
tempMyArraysCombined.push(objName.myArray[x]);
}
objName.myArraysCombined.push(tempMyArraysCombined);
}
edit the last line to:
function prePickNumbers(objName, theNum, theSumNum, theMaxNum, theMinNum) {
/* your code */
objName.myArraysCombined=tempMyArraysCombined; //edit this line not push() but =
}
now there are no "UNDEFINED" in output html.
:)

Related

Tests fail when concatenating nested array in JavaScript

Implemented a Radix Sort which sorts a list of numbers. Here is my code:
function getDigit(number, index, lengthOfLongestNumber) {
let numberString = number.toString();
numberString = numberString.padStart(lengthOfLongestNumber, '0');
return parseInt(numberString[index], 10) || 0;
}
function getLengthOfLongestNumber(numbers) {
// return Math.floor(Math.log10(Math.max(...numbers))) + 1;
let largestNumber = 0;
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] > largestNumber) {
largestNumber = numbers[i];
}
}
return largestNumber.toString().length;
}
function radixSort(numbers) {
const lengthOfLongestNumber = getLengthOfLongestNumber(numbers);
for (let i = lengthOfLongestNumber - 1; i >= 0; i--) {
const buckets = new Array(10).fill().map(() => []);
while (numbers.length) {
const number = numbers.shift();
buckets[getDigit(number, i, lengthOfLongestNumber)].push(number);
}
for (let j = 0; j < 10; j++) {
// numbers = numbers.concat(buckets[j]); ---> uncomment this line and comment out the following while loop
// numbers = [...numbers, ...buckets[j]]; ---> or uncomment this line and comment out the following while loop
while (buckets[j].length) {
numbers.push(buckets[j].shift());
}
}
}
return numbers;
}
Tests fail when I merge buckets array into numbers array using concat() in radixSort function (inside inner for loop). But it somehow passes if I use while loop instead.
You can see and run tests in CodeSandbox.
Why is this happening? What is the difference between them that causes tests fail?
For the returned array it doesn't matter which of those alternatives you use, but if the tests expect you to sort the given array, so that after the call the input array has been sorted itself, then indeed, the commented-out alternatives will not work. This is because those alternatives assign to numbers instead of mutating it.
Just check the difference between the alternatives when ignoring the returned array, but looking at the given array:
let arr = [521, 219, 100, 422, 889, 529, 491, 777, 641, 882, 229];
radixSort(arr);
console.log(arr);
The commented-out alternatives will log an empty array.
The correct version mutates numbers, and does not assign a (new) array to it.
To avoid the loop, you can do this mutation also like this:
numbers.push(...buckets[j]);
And you can even replace the for loop around that statement, with just this line:
numbers.push(...buckets.flat());

Javascript - Arrays - for-loop to forEach

Given an array of integers where every value appears twice except one, find the single, non-repeating value.
Follow up: do so with O(1) space.
1) This is incorrect, the idea is to iterate through twice and compare if any value the first time around is not equal to a the 2nd go around. If not, push the non equal value into a new array and return that.
2) Is forEach pretty much the same as a for-loop?
How could this be rewritten with a forEach?
This is not giving me the output I'd like, which for this example,
should just return 4
CODE
const nonRepeat = arr => {
let newArray = [];
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length; j++) {
if (arr[i] !== arr[j]) {
newArray.push(arr[i])
}
}
}
return newArray
}
console.log(nonRepeat([2, 5, 3, 2, 1, 3, 4, 5, 1]));
Convert from for loop to forEach loop
for
for (let i = 0; i < arr.length; i++) { [code] }
forEach eliminates need to create the iterative variable ( for example, i) and always checks every element in the array
arr.forEach( [code] )
See Here for Additional Syntax Help

Whats wrong with this piece of code?

Trying to figure out what's wrong with this piece of code.
//Code to return the sum of all values in an array
var x = [ 1,2,3,4,5 ];
//Function to return sum of values in an array
function sum(arr) {
var sum = 0;
for (i=1; i < arr.length; i++) {
sum = sum + x[i];
}
return sum;
}
What will be the value of sum(x)?
There's a couple issues here, some are worse than others
First of all you should delcare i as a variable, i=0 -> var i = 0
Then you need to start your for loop at 0 instead of 1 for(var i = 1 -> for(var i = 0 Arrays in javascript (and pretty much every other language) are 0-indexed. That means the first item is arrayName[0] not arrayName[1]
Then you were accessing your value in the array wrong you need to use arr[i] not x[i]. You want to access the value passed to the function, not the actual array you created before.
Line 8 can be shortened using += and was also missing a semicolon
//Code to return the sum of all values in an array
var x = [1, 2, 3, 4, 5];
//Function to return sum of values in an array
function sum(arr) {
var sum = 0;
for (var i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
console.log(sum(x)); //15 -- it works! (1+2+3+4+5=15)
As others have stated the issue is that arrays, and most other things in programming, are zero-indexed.
May I suggest an alternative stylistic choice...
var x = [ 1,2,3,4,5 ];
//Function to return sum of values in an array
var sum = function (arr) {
return arr.reduce(function(a,b){return a+b;})
}
console.log(sum(x));
Though, at this point the function is one line of code, and not really worth wrapping in a function. With things like that I simply do it inline.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
As #user6188402 mentions, i must start at 0.
Here's why:
var x = [ 1,2,3,4,5 ]; creates an array whose index starts at 0, so:
x[0] = 1
x[1] = 2
x[2] = 3
x[3] = 4
x[4] = 5
If you do sum = sum + x[i]; starting at 1, the answer will be 14 instead of 15

Delete Record From Javascript Array Object

i have a java script array object and i want to delete items from a specific index in that object, i have a comma separated string of that indexes. problem is that when i delete it using splice array indexes got changed, and other indexes's object not got deleted.
var DeletedConditions="3, 5, 19, 50";
for (var k = 0; k < DeletedConditions.split(", ").length; k++) {
ConditionObject.splice(DeletedConditions.split(", ")[k], 1);
}
DeletedConditions string can be anything.
please help me out. how to get this done.
First of all, I suggest you officially turn the indexes into a formal array. Having a string as an index reference, you are prone to missing a split shall there be a case where the values are not separated by ,
Then the code:
var content = ['foo', 'bar', 'baz', 'bam', 'dom', 'zok'],
deleteIndexes = [5, 1, 3],//should delete zok, bar, bam
i;
//sort from least to greatest: [1, 3, 5]
deleteIndexes.sort(function(a, b) {
return a - b;
});
//we loop backwards (performance enhancement)
//now we loop from greatest to least
//we now splice from greatest to least
//to avoid altering the indexes of the content as we splice
for (i = deleteIndexes.length; i-- > 0;) {
content.splice(deleteIndexes[i],1);
}
console.log(content); //["foo", "baz", "dom"]
​
You can always decrement the k iterator after splicing inside the loop:
k--;
var DeletedConditions="3, 5, 19, 50";
var list = DeletedConditions.split(", ")
for (var k = 0; k < list.length; k++) {
// using splice here
list.splice(k,1);
k--;
}
console.log(list.join(', '))
Removing an item from the beginning of the array shuffles the later elements up and changes their indices, as you've observed. But if you go through the list of items to remove backwards then it will remove the later elements first so the indices will still be correct for the elements closer to the beginning of the array.
Also, please don't do the .split() operation on every loop iteration - the inefficiency might not make much difference on a string with four numbers in it, but it makes the code kind of messy and on principle it is just kind of yucky.
var DeletedConditions="3, 5, 19, 50",
delCondArr = DeletedConditions.split();
for (var k = delCondArr.length - 1; k >= 0; k--) {
ConditionObject.splice(delCondArr[k], 1);
}
If there's a possibility that the DeletedConditions strig might not be ordered just add a .sort() after you split it:
delCondArr = DeletedConditions.split().sort(function(a,b){return a-b;});
...in which case you don't need to loop backwards.
It might be easiest to copy the original array, omitting the deleted items in the process. Something like this would do the trick...
var DeletedConditions="3, 5, 19, 50";
DeletedConditions = DeletedConditions.split(', ');
var newConditionObject = [];
for(var k = 0; k < ConditionObject.length; ++k) {
if(DeletedConditions.indexOf(k) !== -1) { continue; }
newConditionObject.push(ConditionObject[k]);
}
// result is in `newConditionObject`
console.log(newConditionObject);
var fruits = new Array("apple", "banana", "grapes", "oranges","mosambi","aaa","bbb","ccc");
var DeletedConditions="1,3,4,5";
var indexArray = new Array;
indexArray = DeletedConditions.split(",");
for (var i = 0; i < indexArray.length; i++) {
fruits.splice(indexArray[i], 1);
}

How to delete multiple items of an array by value?

I am trying to make a removeAll() function, which will remove all elements of an array with that particular value (not index).
The tricky part comes when we make any change to the loop, the indexes tend to move around (making it very hard to make it work like we want) and, restarting the loop every time we make changes is very inefficient on big arrays.
So far, I wrote my own arr.indexOf function (for older IE support), it looks like this:
function arrFind(val, arr) {
for (var i = 0, len = arr.length, rtn = -1; i < len; i++) {
if (arr[i] === val) {
return i;
}
}
return -1;
}
It is easy to remove elements like this:
var myarray = [0, 1, 2, 3, 4];
var tofind = 2;
var stored_index = arrFind(tofind, myarray);
if (stored_index != -1) {
myarray.splice(stored_index, 1);
}
alert(myarray.join(",")); //0,1,3,4
However, as I pointed out earlier, when doing this while looping, we get in trouble.
Any ideas on how to properly remove array items while looping through it?
Loop in reverse order or build a new array with the items that are not to be removed.
Every new browser has an Array filter method:
var myarray=[0,1,2,3,4];
var removal=2;
var newarray=myarray.filter(function(itm){return itm!==removal});
Try this one. You just have to check the indices of the numbers you would like to remove. I have added additional elements in your array.
var myarray = [0, 1, 2, 3, 2, 2, 2, 5, 6];
var indicesToRemove = new Array();
for(i=0;i<myarray.length;i++){
if(myarray[i]===2){ //let's say u wud like to remove all 2
indicesToRemove.push(i); //getting the indices and pushing it in a new array
}
}
for (var j = indicesToRemove.length -1; j >= 0; j--){
myarray.splice(indicesToRemove[j],1);
}
alert(JSON.stringify(myarray)); //myarray will be [0,1,3,5,6]
I wrote this little function where arr is the original array and d1, d2 the values you want removed. I wonder how it could be generalized to an arbitrary number of values to be removed. Well, I'm just a beginner.
function destroyer(arr, d1, d2) {
var lean =[];
for (var i = 0; i<arr.length; i++) {
if (arr[i] != d1 && arr[i] != d2) {
lean.push(arr[i]);
}
}
return lean;

Categories