I am currently working on a sorting visualizer project to try and better understand JavaScript.
My issue is that I am calling 'push' on this array, and am getting the error
Cannot read properties of undefined (reading 'push')
After trying to research this problem, I understand that it means that the thing I am trying to reference with push is undefined, but I am failing to understand why this is the case.
Due to my lack of understanding, I cannot post a smaller sequence of code.
This is what my code does:
- I run some sorting algorithms.
- I output array columns to the screen that get visually sorted.
The end goal will be similar to this video. For my algorithm functions, I have a separate "animations" array that starts off as empty and then gets filled with pairs of array indices and colors.
After finishing the algorithm, I end up with this "animations" array that tells me how to manipulate the array on the screen to get it sorted.
Below is a part of my program, in which I am trying to implement heapsort.
export function getHeapSortAnimations(array) {
const animations = [];
if (array.length <= 1) { return array; }
heapSortHelper (array, animations);
return animations;
}
function heapSortHelper(array, animations) {
let len = array.length;
for (let i = Math.floor(len / 2) - 1; i >= 0; i--){
heapify(array, len, i, animations);
}
for (let i = len - 1; i > 0; i--) {
let temp = array[0];
array[0] = array[i];
array[i] = temp;
heapify(array, i, 0, animations);
}
}
function heapify(array, size, i, animations){
let max = i;
let right = rightChildIndex(i);
let left = leftChildIndex(i);
if (left < size && array[left] > array[max]) {
animations.push([0, 'red']);
max = left;
}
if (right < size && array[right] > array[max]) {
max = right;
}
if (max != i) {
let temp = array[i];
array[i] = array[max];
array[max] = temp;
heapify(array, size, max);
}
}
function parentIndex(index){ return Math.floor((index-1)/2); }
function leftChildIndex(index){ return (2 * index 1); }
function rightChildIndex(index){ return (2 * index 2); }
Note: In the first if statement of the "heapify" function, I am passing the index 0 along with the color 'red', which doesn't really make sense in regards to the algorithm; basically, anywhere I try to push something into my animations array I get:
Cannot read properties of undefined (reading 'push')"
The main reason this is so confusing is that I have a separate "Quicksort" file (code below), where I use this animations array. Here, I push values into it all over the place, without getting an error:
export function getQuickSortAnimations (array) {
const animations = [];
if (array.length <= 1) { return array; }
console.log("unsorted array: " array);
quickSort(array, 0, array.length-1, animations);
console.log("animations: " animations);
console.log("sorted array: " array);
return animations;
}
function quickSort (array, lowIndex, highIndex, animations){
if (lowIndex >= highIndex) {
animations.push([lowIndex, 'purple']);
return;
}
let pivot = array[highIndex];
let leftPtr = partition(array, lowIndex, highIndex, pivot, animations);
quickSort(array, lowIndex, leftPtr-1, animations);
quickSort (array, leftPtr 1, highIndex, animations);
}
function partition (array, lowIndex, highIndex, pivot, animations){
let leftPtr = lowIndex;
let rightPtr = highIndex-1;
// Coloring our first instance of leftPtr and our Pivot(highIndex)
animations.push([highIndex, 'yellow']);
animations.push([leftPtr, 'red']);
animations.push([rightPtr, 'red']);
while (leftPtr < rightPtr) {
while ((array[leftPtr] <= pivot) && (leftPtr < rightPtr)){
// Send rightPtr to animations once to decolor
animations.push([leftPtr, 'turquoise']);
leftPtr ;
// Send new leftPtr to animations to color new array bar
animations.push([leftPtr, 'red']);
}
while ((array[rightPtr] >= pivot) && (leftPtr < rightPtr)){
// Send rightPtr to animations once to decolor
animations.push([rightPtr, 'turquoise']);
rightPtr--;
// Send new rightPtr to animations to color new array bar
animations.push([rightPtr, 'red']);
}
// temp variable holds the value of our leftPtr index while we perform swap
let temp = array[leftPtr];
// swap our leftPtr with our rightPtr in animations
animations.push([leftPtr, array[rightPtr]]);
// swap our rightPtr with our leftPtr in animations using temp
animations.push([rightPtr, temp]);
// same swap as above but with the our actual array
[array[leftPtr], array[rightPtr]] = [array[rightPtr], array[leftPtr]];
}
animations.push([highIndex, 'turquoise']);
if (array[leftPtr] > array[highIndex]) {
// temp variable holds the value of our leftPtr index while we perform swap
let temp = array[leftPtr];
// swap our leftPtr with our highIndex in animations
animations.push([leftPtr, array[highIndex]]);
// swap our highIndex with our leftPtr in animations using temp
animations.push([highIndex, temp]);
// same swap as above but with the our actual array
[array[leftPtr], array[highIndex]] = [array[highIndex], array[leftPtr]];
animations.push([leftPtr, 'purple']);
}
else {
leftPtr = highIndex;
animations.push([leftPtr, 'purple']);
}
return leftPtr;
}
I just don't understand why I can push values into this array in one file, but then in another file that is very similar, I can't seem to push any values into the array at all.
CodePudding user response:
The error you got is due to your heapify
function. It expects 4 parameters, the last one is your animation
array, but inside of this function you called itself recursive with 3 parameters only. So you are writing to animation
array but not every time, due to sometimes it is undefined
. I added a console log and a comment in your code to show the issue.
function getHeapSortAnimations(array) {
const animations = [];
if (array.length <= 1) {
return array;
}
heapSortHelper(array, animations);
return animations;
}
function heapSortHelper(array, animations) {
let len = array.length;
for (let i = Math.floor(len / 2) - 1; i >= 0; i--) {
heapify(array, len, i, animations);
}
for (let i = len - 1; i > 0; i--) {
let temp = array[0];
array[0] = array[i];
array[i] = temp;
heapify(array, i, 0, animations);
}
}
function heapify(array, size, i, animations) {
console.log(JSON.stringify(animations));
let max = i;
let right = rightChildIndex(i);
let left = leftChildIndex(i);
if (left < size && array[left] > array[max]) {
animations.push([0, "red"]);
max = left;
}
if (right < size && array[right] > array[max]) {
max = right;
}
if (max != i) {
let temp = array[i];
array[i] = array[max];
array[max] = temp;
// Here: heapify function expects 4 parameters. 3 only.
heapify(array, size, max);
}
}
function leftChildIndex(index) {
return 2 * index 1;
}
function rightChildIndex(index) {
return 2 * index 2;
}
const data = [4, 2, 8, 5, 6, 1];
try {
const animations = getHeapSortAnimations(data);
console.log(JSON.stringify(animations));
} catch (e) {
console.error(e);
}