How do you check for equality among arrays of equal length

Hi @kernix and sorry for my delayed reply. Im glad you find my solution helpful and you try to fit in your project. @colinthornton guided you very well into how you can apply the solution in your project.

Your data is already in the form of array of objects, you need not do any specific adjustments. You want to access the steps array in every object, to compare it to an array the user inputs and return the one which matches. This is why i use the array find method. It would sift throught your json data(presumable array of objects) and return the one which matches our criteria. The compareArrays function is the criteria, which we provide indirectly as a callback to the find method. Only if it returns true(we found matching steps), it would return the object.
Basically the arrOfObjects variable in my code, represents your json data. The arrWeLookFor represents the user input array. When we call compareArrays, we provide two arrays as a parameter, the array we want to match and the current steps array we compare. In order for the code to work in your case, you will need to change the arr parameter with the name of the object property we destructure(steps). Ofc, you could use different approach from destructuring, if you find it confusing.
This is how it might look in your case:

const result=arrOfObjects.find(({steps})=>{
  return compareArrays(steps, arrWeLookFor)
})

// OR

const result=arrOfObjects.find((obj)=>{
  return compareArrays(obj.steps, arrWeLookFor)
})

With some adjustments we could even go step further and provide the compareArrays directly as callback to find, but this might make the code less intuitive to understand.

I’m working on it now - I got confused by your var names and mine but I have it now. However, I have what seems to be a problem. My steps property is in each of 136 objects. I can console.log(data) and I get 5 results - 1 for each of my test notes array all with 136 objects in the JSON file. I guess I will have to use a for loop inside the for loop I am in or a forEach. Here is what I have using your code block:

function compareArrays(arr1, arr2) {

  if (arr1.length !== arr2.length) return false

  for (let index in arr1) {
    if (arr1[index] !== arr2[index]) return false
  }

  return true
}

// what do I put in the data array brackets? [j] for another loop for j < data.length?
const arrOfObjects = data[?].steps

// const arrWeLookFor = [2,3,4,1] don't need this, just use noteSteps

const result=arrOfObjects.find(({steps})=>{
  return compareArrays(steps, noteSteps)
})

console.log(result)  

Let me try another for loop…

I’m getting a little confused. is arr in return compareArrays(arr, arrWeLookFor) supposed to be arrOfObjects? Or is it supposed to be steps?

I keep getting errors in the console. I get undefined for this:

const arrOfObjects = data[i].steps

        const result=arrOfObjects.find(({steps})=>{
          return compareArrays(arrOfObjects, noteSteps)
        })

        console.log(result) 

And replacing arrOfObjects with steps on the return line inside result I get:

TypeError: Cannot read properties of undefined (reading 'length')
    at compareArrays (script.js:108:20)
    at script.js:121:18
    at Array.find (<anonymous>)
    at script.js:120:35

Line 108 is the line if (arr1.length !== arr2.length) return false and I assume it is referring to the 1st parameter array steps in compareArrays. I’m wondering if I should edit my JSON file to have steps as the top-most property in each object and then nest all the other properties within it.

Back way up. You were handed a function for checking if two arrays are equal.

You can just drop that function as is into your code. But you need to know where and how to call it. Wherever you call it, you need to be passing in two arrays.

It’s hard to help you debug your use of the function without seeing your full code.

I intentionally used different var names, ones that represent something which you can later adjust to the approrpiate data of your project. I did not look into the exact structure of your project, only tackled the more universal task of filtering an array of objects and comparing arrays. Its up to you to be able to apply them in your project :wink:

arrOfObjects.find(({steps})=>{
  return compareArrays(steps, arrWeLookFor)
})

It seems like you have troubles udnerstanding how find works, how the callback we provide it works. If it helps, try to see it as a filter, or map method for a moment. It will go throught every element in an array and apply the callback to that element. With this in mind, the parameter steps refers to the current object “steps” property.

const findThree=['one', 'two', 'three'].find(element=>{
  console.log(element)
  return element==='three'
})

// logs one
// logs two
// logs three

console.log(findThree)  //logs three

Here you incorectly assign the array of objects we test, to the steps property in a single object in your data. Like i tried to epxlain earlier, the arrOfObjects variable is reference to your json file. If i assume correct, your json file goes under the name data. If this is true, you want to apply the find method directly to your data(your data is an array!).

data.find(({steps})=>{
  return compareArrays(steps, noteSteps)
})

In case its still unclear, the compareArrays function is designed to take two arrays and tell us if they are identical(true), or not(false). The order of parameters doesnt matter. I used “arr” as reference to the array we test in your object, i.e. “steps”, so to work in your case, you need change it to the appropriate name.

PS: there should be no need to use loops(or nesting loops) or forEach method, unless im missing something crucial.

1 Like

I’m teaching myself JavaScript so I’m a newbie and there is a lot that I still have to learn. I was not able to finish the FCC Javascript course because the Intermediate Algorithms section threw me for a loop. So I started building projects.

Let me look into find and read over the rest of your reply - thanks for all your help!

Understanding what types of data are in each variable and manipulating that data is a key skill. Going back at looking at some of those algorithms challenges probably is a good idea. They cover exactly the sort of skills you are describing here, but they are a smaller, more isolated version of the problems.

You might also be surprised at how much you have learned by working on this project. There is no rule saying you cannot do projects and challenges at the same time.

1 Like

I’m watching the video Learn JavaScript - Full Course for Beginners as an alternative to going through all the lessons. So far it matches the lessons exactly.

However you want to do it, in whatever format, I highly encourage you to do some intermediate algorithm challenges. The core of the task you are asking for help with here is basically equivalent in difficulty to a freeCodeCamp Intermediate Algorithms challenge.

I guess that is what I have to do because I can’t make this work. I didn’t catch that Sylvan had the return array with the values in the same index position - I didn’t look at the function close enough. So I sorted both of the arrays and I’m still getting 5 undefined logs in the console.

The problem I think is with arrOfObjects:

// his:
const arrOfObjects=[{arr: [1,2,3,4]}, {arr: [2,3,4,1]}]
// mine: 
const arrOfObjects = data
// where data is the array in the JSON file that has a property of "steps"

I have no idea why my code does not work.

It does work in my CodePen for the project but not on my local machine. It’s easiest to see the results in the CoePen console - it’s exactly what I want, though I did have to use a conditional for console.log(result) because something is returning undefined. Probably the one note that does not have a matching steps array. I had to add a variable (chordIntervals) at the top for 8 minimal objects, 3 of which had matching steps arrays for the notes entered. The other 5 were of different lengths or had a matching length but different steps.

However, I duplicated your code block that worked in CodePen for my js file but I am getting undefined when I replaced chordIntervals with data from the fetch of my JSON file. That is odd because I can console log the entire data object on Submit and even write to the DOM. So I guess the problem has something to do with the function that is fetching the file. I have to figure out what it is that is undefined - data from the fetch or my steps array from the Submit button.

So just change every instance in Sylvan’s code that accesses the key named arr to code that accesses a key named steps, right?

I did and it worked in CodePen:

function compareArrays(arr1, arr2) {
  if (arr1.length !== arr2.length) return false

  for (let index in arr1) {
    if (arr1[index] !== arr2[index]) return false
  }
  return true
}

const arrOfObjects = chordIntervals;
const arrWeLookFor = noteStepsSort; 

const result = arrOfObjects.find(({steps})=>{
  return compareArrays(steps, arrWeLookFor)
})

Where chordIntervals is a var at the top that has 8 objects from my JSON file. Then I copied the code block into my getJson function below the code block below and changed chordIntervals to data:

function getJson() {
fetch('./js/chord-intervals.json')
  .then(res => res.json())
  .then(data =>  {
// function here

But t doesn’t work. I think I am getting undefined for the function. I need to sort the steps property for all the objects and then I’ll read up on fetching JSON and try to figure out what I am doing wrong.

This is now redundant. You should be able to directly use your ready variavles:

const result = chordIntervals.find(({steps})=>{
  return compareArrays(steps, noteStepsSort)
})

One thing i didnt bother understand is, why do you sort the steps? Is there a chance, sorting them can make them not match with the appropriate object.steps?
Ofc there is the chance the find method actually dont find a match, in such case you should create some condition, to handle it.

It works on CodePen, it’s my function where I am fetching the JSON file where it stops working. I think it must be an issue with the scope of the variables. My getJson() function is not recognizing the property steps when trying to find a match. and just returns 5 values for the last item.

I noticed you had the matching array in the same order as what you were trying to match so I assume that was deliberate. I just changed the order in Codepen and did not match an object that it did when it was sorted. However, that creates a problem where another property does not match the steps. I’ll figure that out somehow or else I’ll move on to a different project idea.

When you fetch the data, are you able to properly log it in the console and does the objects contain a “steps” property?
You can try debug the find method(or use another more appropriate method to map the data), see if you get the proper objects data:

data.find(obj=>{
  console.log(obj)
})

Here is a small custom function, which can be used to map data with your format and check if there is “steps” prop and if its the right type(array):

//example data with wrong values
const testData=[{steps:[1,2,3,4]}, {steps: 'wrong type'}, {notSteps: [1,2,3,4]}]

testData.forEach((obj, i)=>{
  if (!obj.hasOwnProperty('steps')) {
    console.log(`Data object #${i} has no "steps" property: `, obj)
  } else if (!Array.isArray(obj.steps)) {
    console.log(`Data object #${i} has wrong type of "steps"- ${typeof obj.steps}: `, obj.steps)
  }
})

//  Data object #1 has wrong type of "steps"- string:  wrong type
//  Data object #2 has no "steps" property:  { notSteps: [ 1, 2, 3, 4 ] }

When working with fetched data, its important to make sure its in the right format, before you use it and something backfires.

If you move on to another topic to learn, pinpoint what was hard for you to udnerstand or utilize so far in the project, like array methods, keeping up with functions, or maybe manipulating different data types. Look into docs and exercises concerning those topics, so you get better at them. It certainly would help you to challenge yourself in the advanced algorithms on FCC. It certainly is not some artsy thing to do, but it can prove of great value when tackling such problems.

I was able to log the entire JSON object (data) but not data.steps. I started over and added the json object in a js file and call it in my HTML file before my main js file. Maybe I have to create my own API or something but what seemed simple is now creating nothing but problems. I thought this would be a good 2nd portfolio project but I’m too upset right now to even try anything else.

i was looking at your git repo.

//line 88
noteStepsSort = noteSteps.sort();

You initialize noteStepsSort variable, without keyword(const/let/var).

Some other things i noticed. Your noteStepsSort has same value as noteSteps. The sort method seems to provide no change.

//line 119
const result = data.find(({steps})=>{
  return compareArrays(data, noteStepsSort)  //change "data" to "steps"
})

Here you try to compare “data”, instead of “steps”.
When i changed data to steps, i got only 2 undefined results, the other 3 attempts were successful to find object with matching steps in your json file

noteStepsSort: I missed that I didn’t use let on that, but it does sort noteSteps. It won’t do anything to the steps property in the JSON because I manually sorted them.

I may have pushed it sometime yesterday before I came close to getting things working. You’ve already helped enough, don’t bother yourself further. I already changed a bunch of things like ripping out my getJson function. I’ll see if using let on noteStepsSort does something…I’m just too depressed right now to try and figure out what I am doing wrong.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.