How do you check for equality among arrays of equal length

… and equal data types?

I’ve tried a number of things and I can not get anything to work. I’m not even sure what the problem is. Is there a way to return values from a for loop?

Anyway, I did everything I want to do with this project except the next step. I have:

  1. an array of numbers and I have a JSON file where one of the object properties is an array of numbers.
  2. I was able to use an if statement to only look at the property’s value (which is an array) if it is the same length.
  3. I want to get only the one object that has the array that has the same numbers as my first array.

I have a CopePen of all the code except the fetch for the JSON file and a GitHub repo.

All I need to do is find the one object with the matching array then the rest is easy. If you click the submit button in CodePen I have console logs that show the array for the 6 default values in the 6 input fields.

The fields all have 0’s in them which represent the open strings on a guitar and are the notes E, A, D, G, and B (unique notes only so no 2nd E). Those notes equal an Em11 chord and the array for those notes (the “steps” away from the note E) have a corresponding record for the m11 chord in the JSON file. Here is that object:

{
	"Chord": "m11",
	"Intevals": ["1", "♭3", "5", "♭7", "11"],
	"steps": [0, 3, 7, 10, 5],
	"Equal Chords": [{"key": 10, "name": "9sus"}, {"key": 3, "name": "6 add9"}],
	"Chord Substitutes": [{"key": "", "name": ""}],
	"scales": {
		"Major Scale": ["2nd", "3rd", "6th"],
		"Minor Pentatonic": ["1st"],
		"Blues Scale": ["1st"],
		"Harmonic Minor": [""],
		"Melodic Minor": ["2nd"],
		"Whole Tone": [""],
		"Augmented": [""],
		"HW Diminished": [""],
		"Major Bebop": ["2nd", "3rd", "6th"],
		"Minor Bebop": ["2nd", "3rd", "6th"]
	}
},

Does anyone know how to compare to arrays for equality?

If by equality you mean that the two arrays have the same length and the exact same value for each array item then couldn’t you just loop through one array and compare each value in it to the other array? I believe you said these arrays just hold numbers, so strict equality to compare values should work just fine.

But if you were asking if JS had some native way to do this, the answer is no. You have to create your own array comparison function, or as @JeremyLT suggested, use a library that does it for you.

2 Likes

Objects and arrays, you check the same way. We usually say that two objects/arrays are the same if they have the same things in the same places. Does the first element of arr1 match arr2? Does the second? Etc.

There are some libraries that can do that for you, or you can roll your own small comparison function.

Edit: dumb typos

1 Like

I tried a for loop and a forEach and neither worked. Now I am doing that while in a for loop, but I don’t see how that is a problem. I even sorted the main array I want to find a match with the JSON file arrays which I also sorted.

What didn’t work? If you have two arrays, a and b, it should be relatively easy to go through them and compare their values at each index to make sure they are the same. Don’t try to get too tricky at first. Create a function that takes two arrays, verify they have the same length and if so then use a for loop to go through one and compare the values of both arrays at the current index.

1 Like

This is a project for my portfolio…so I have not used ANY libraries for anything.

And “YES” - I sorted my main array and every array in my JSON file of the same length and my console.log returned every array in the file with the same length, instead of the one I know that is a match. It’s getting late and I was stressed so maybe I am thinking about this the wrong way.

I have other problems/issues which I was going to ask for help on - I don’t think they are related. But one is that I’m doing everything in one function attached to an event listener. In that function, I have 2 for loops and I don’t know how to return a value from the loop.

It’s late…time to call it a night - thanks for the reply.

As @bbsmooth said, we can check if two arrays of the same length have the same items, regardless of the order. This can be acheived using the includes keyword.
Here is a very basic and simple working example I can give to elaborate on this.

let a = ["cat", "dog", "pen", "pencil", "car", "motorbike", "macbook"]
let b = ["dog", "cat", "pen", "car", "macbook", "pencil", "motorbike"]

//Here we have initialized two arrays a and b with the same length and values but of different order.

function chkIfContains(array1, array2){
    let items = [];
    if(array1.length == array2.length){
    for(let i = 0; i < array2.length; i++){ 
        if(array1.includes(array2[i]) == false){
            return "not the same"
        }else{
            items.push(array2[i])
        }
    }
    }
    return items;
}

What this function does is check if the two arrays are of same length, if so use a for loop to loop through each item of the second array. Then checks if it is included in array1 with the help of includes. If the program detects that an item isnt included, it returns “not the same” and in the process stops the function from executing. Else, it pushes the values to a variable named item (which at the start is an empty array ). The return item will only execute if the two arrays have the same items and length.

The purpose of this was to show that it is possible to do this with a simple for loop. In your case, rather than returing items, you might want to return true or so on.

You can also sort the arrays and compare them using JSON.stringify (should be fine for your use case and it’s simple).

Example (I added Lodash as well):

import lodashIsequal from "https://cdn.skypack.dev/lodash.isequal";

let a = ["cat", "dog", "pen", "pencil", "car", "motorbike", "macbook"];
let b = ["dog", "cat", "pen", "car", "macbook", "pencil", "motorbike"];
let c = ["test", "dog", "cat", "pen", "car", "macbook", "pencil", "motorbike"];

console.log(lodashIsequal(a, b)); // false
console.log(JSON.stringify(a) === JSON.stringify(b)); // false

a.sort();
b.sort();
c.sort();

console.log(lodashIsequal(a, b)); // true
console.log(JSON.stringify(a) === JSON.stringify(b)); //true

console.log(JSON.stringify(c) === JSON.stringify(b)); // false
console.log(lodashIsequal(c, b)); // false
1 Like

I thought that was something I tried last night but let me try it again later - thanks!

I did not try that. Let me try and hopefully it works - thanks!

this is great way to solve this challenge!

I looked up on the matter of your challenge and u put up some basic solution on how i would solve it:

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=[{arr: [1,2,3,4]}, {arr: [2,3,4,1]}]
const arrWeLookFor=[2,3,4,1]

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

console.log(result)  //{ arr: [ 2, 3, 4, 1 ] }

Ive created a function which compare two arrays(if they are identical). I made a mock array, which includes array of objects and used the find method to return the object which owns identical array to the one we are looking for.
I hope you can utilize some of the ideas to implement in your own project to acheive your design.

PS: let me know if you need clarification anywhere on the code logic

Thanks, let me try that. I definitely the arr I am looking for to be the one that is returned after the match. So you tried it and it works? Great, let me try it - THANKS!

Sorry for the late reply. I’ve been running around and did not have the time.

const arrOfObjects may be a problem. Here is an image of a console.log for:

if (chord.steps.length == noteSteps.length) {
  console.log(chord.steps);
}

Where chord.steps is the arrays from my JSON file that are the same length of the array I want to find a match for (noteSteps).

It’s not an array of objects with a key that has a value of the matching arrays. I’ll have to figure out how to turn ALL my chords.steps properties into an object or to tweak your code.

Are both chordSteps and noteSteps arrays of numbers?

1 Like

Yes, with a min of 0 and a max of 11. Do you have a different idea? And FYI, I do not have an array of chordSteps - the first property in each object is called “Chord”, but it’s the second one called “steps”. I have 136 objects in the JSON file all with the property of “steps” that I need to find a match for.

I’m trying to create the code @Sylvant provided because I got the same results in CodePen. I was able to add a key to each of the noteSteps arrays but I got them into an object, but I can’t get them all into an array. - I’m inside a for loop. The image above is a mistake - I stupidly was trying to do something inside of a forEach method in the for loop.

I do not think I will need the forEach code block. Once I have a match, and I might have more than one, then I’ll output everything from the matching object.

I don’t completely understand your data structure.

It sounds like there’s a chord object that looks like this:

{
  steps: [1, 2, 3]
}

And a noteSteps array which looks like this:

[1, 2, 3]

In which case the compareArrays function posted above could be used as such:

compareArrays(chord.steps, noteSteps)

If that’s not how the data structure looks like, then please provide a minimal reproduction of what it is (something like what I posted above, not just a link to your entire project’s source code), specifically so we can divine where these two arrays are and what they look like.

1 Like

Almost. That is what noteSteps looks like though in random order. I have a JSON file called chord-intervals.json and here is an example of one object in that file:

{
	"Chord": "m11",
	"Intevals": ["1", "♭3", "5", "♭7", "11"],
	"steps": [0, 3, 7, 10, 5],
	"Equal Chords": [{"key": 10, "name": "9sus"}, {"key": 3, "name": "6 add9"}],
	"Chord Substitutes": [{"key": "", "name": ""}],
	"scales": {
		"Major Scale": ["2nd", "3rd", "6th"],
		"Minor Pentatonic": ["1st"],
		"Blues Scale": ["1st"],
		"Harmonic Minor": [""],
		"Melodic Minor": ["2nd"],
		"Whole Tone": [""],
		"Augmented": [""],
		"HW Diminished": [""],
		"Major Bebop": ["2nd", "3rd", "6th"],
		"Minor Bebop": ["2nd", "3rd", "6th"]
	}
},

The 3rd property is steps and I need to find the one(s) that match noteSteps. Here is a link to the JSON file so you can take a look if you want but it’s just a repeat of the code block above.

I used let keyArray = {"arr": noteSteps}; to get the image below. Now how to I add all those objects into one array to use the code block given by Sylvan?

arr-for-fcc

Ok, just noticed that the 5 arrays for the 5 notes (keyArray) are a repeat of the last noteSteps. I may need the forEach after all. Unbelievable how difficult the last part of this is.

FYI, the 5 notes have the following “step” arrays:

[0, 5, 10, 3, 8]
[7, 0, 5, 10, 2]
[2, 7, 0, 5, 9]
[9, 2, 7, 0, 4]
[5, 10, 3, 8, 0]

I don’t see why you can’t access the steps property above and compare it to noteSteps.

compareArrays(bigObjectName.steps, noteSteps)

Oh, you’re right - I misread Sylvan’s code - just wasted a couple of hours. I’ll try it in the morning. I got too caught up with the code. I’ll post tomorrow with my results…