I have an array that I need to sort, and then split them into smaller arrays where the addition of the numbers to the smaller arrays are reversed at every other iteration. I would want to be able to choose how many numbers fit into each smaller array, and how many smaller arrays there are.
An example would be:
numbersArr = [10, 5, 13, 25, 30, 2, 18, 11, 22]
sortedNumbersArr = [2, 5, 10, 11, 13, 18, 22, 25, 30]
avgOfSortedNumbers = 15
smallerArrs = [[ 10, 11, 30 ], [ 5, 13, 25 ], [ 2, 18, 22 ]]
avgOfSmallArrs = 17 14 14
You can see that at every even iteration,the addition of numbers from the sortedNumbersArr switches
switched -> not switched -> switched
[10, 5, 2] -> [11, 13, 18] -> [30, 25, 22]
I am doing this so that the average isn't extreme on both ends.
The problem is that the code works for when I want 3 smaller arrays and 3 values in each smaller array. If I try changing this to 5 smaller arrays and 2 values in each for example (we would need to add more numbers to the sortedNumbersArr so there are enough values), I get weird results where there are empty values being added and other smaller arrays that are empty.
sortedNumbersArr = [2, 5, 10, 11, 13, 15, 18, 22, 25, 30]
numInsideSmallerArr = 2;
numOfSmallerArr = 5;
smallerArrs = [[ <1 empty item>, 10, <1 empty item>, 18 ], [ <1 empty item>, 11, <1 empty item>, 22 ], [], [ 5, <1 empty item>, 15, <1 empty item>, 30 ], [ 2, <1 empty item>, 13, <1 empty item>, 25 ]]
avgOfSmallArrs = 15, 17, NaN, 17, 13
My current code looks something like this:
// variables to determine resulting array size and how many values it holds
let numInsideSmallerArr = 3;
let numOfSmallerArr = 3;
let sortedNumbersArr = [2, 5, 10, 11, 13, 18, 22, 25, 30];
// variable that holds the resulting sorted/split array
let smallerArrList = [];
let indxA = 0;
// temp variable used to reverse the order
let smallerArrIndex;
// populates the number of smaller empty arrays so values can be added to it
for (let i = 0; i < numOfSmallerArr ; i ) {
smallerArrList[i] = [];
}
// loop through the smaller arrays
for (let i = 0; i < numOfSmallerArr; i ) {
// loop through the smaller array
for (let j = 0; j < numInsideSmallerArr; j ) {
smallerArrIndex = j;
// reverse order at every even iteration
if (i%2 === 0) {
smallerArrIndex = numOfSmallerArr - 1 - j;
}
// add number to the smaller indexes in small array list
smallerArrList[smallerArrIndex][i]= sortedNumbersArr[indxA];
indxA ;
}
}
console.log(smallerArrList)
I started to program pretty recently and am currently learning data structures and algorithms so I wasn't sure if one already exists for what I am trying to do. Could anyone point me in the right direction of where my logic is incorrect? Any help would be greatly appreciated!
CodePudding user response:
I couldn't really understand the logic you tried to implement in the code where you let the index indxA
traverse the source array from left to right. This follows a different procedure than you described. In the description you explain how one subarray is formed by selecting some particular indices in the source array.
I would work in the following order of actions: create each sub array one after the other completely: so first finish the first sub array (using the logic you described), then the second, ...etc.
Then the alteration formula you used will work well:
function spread(numbers, chunkSize) {
const length = Math.ceil(numbers.length / chunkSize);
const result = [];
for (let j = 0; j < length; j ) {
const chunk = [];
for (let i = 0; i < chunkSize; i ) {
// Alteration
let source = i * length (i % 2 ? length - 1 - j : j);
if (source >= numbers.length) break;
chunk.push(numbers[source]);
}
result.push(chunk);
}
return result;
}
// Example run
const sortedNumbersArr = [2, 5, 10, 11, 13, 15, 18, 22, 25, 30, 34, 36]
const numInsideSmallerArr = 3;
const result = spread(sortedNumbersArr, numInsideSmallerArr);
console.log(result);