I have a problem with my code for Diff Two Arrays

<%= @topic_view.topic.title %>
<%= @topic_view.topic.average_rating %> <%= @topic_view.topic.posts.count { |p| !!p.custom_fields['rating'] } %>

I have almost succeeded using “for loops”. I would greatly appreciate if someone can explain the two questions I have inserted in the comments of this code. Thanks!

When you have a problem with your code for a challenge, please create a new topic instead of replying to an existing thread. This helps to keep the threads cleaner and helps others to not have to read through other posts first.

I have created this new thread for you. In the future, just add your code in the FCC editor and click the Ask for Help button. This will create a new topic with your code and other relevant information we need to help you.

For now, can you please copy/paste your code into a reply, instead of as a screenshot? We can not test your code without retyping it all.

Thank you.

So there is a little confusion going on here, and it’s a common thing with those learning javascript (and quite a few other languages). And that confusion is based around “When is a variable passed by value vs by reference?”

So first, you need to understand what those terms mean.

  • A variable has a value: a string might be let myStr = 'The quick brown fox'; or a number might be const PI = 3.141, or a Boolean might be let isHidden = true; Each of these clearly indicate what their value is. These are javascript primitive types, and they are always passed by value. So if I did const anotherStr = myStr+' jumped over the lazy dog.';, I have taken the value of myStr and used it within a function expression.
  • A complex variable (one that is not one of javascript’s primitive types) is a little more complicated. If I did const myAnimalArr = ['cat','dog','cow','sheep','frog'];, can the value of that array be expressed in terms of those javascript primitives? The value is the array. So when we assign a complex variable, an array or an object, to another variable, we aren’t referencing its value. We are passing along a pointer to the original variable. So doing const anotherAnimalArr = myAnimalArr; does not, in fact, create a copy of my array. It simply assigns another name to the same space in memory - in effect, we set up a second mailbox that delivers the same mail.

So, given that, when you do

const array1 = arr1;
const array2 = arr2;

you’re not doing what you think you are. You want to create a copy of those arrays, but that’s not what’s happened. Instead, you now have two variables, array1 and arr1, that point to the same piece of information in memory. If either of them are changed, because the reference the same data, then both of them are changed.

If you want to copy an array to another variable, you need to use a different trick. There are a few different options. The shortest and cleanest is using the spread operator:

const array1 = [...arr1]; // this 'spreads' out the values of arr1, then wraps them in an array bracket, thus making them a new array.

Another option would be to use an array method that returns a new array, and simply not modify the array. Here are some options:

const array1_1 = arr1.concat(); // typically, this is used to join two arrays, but if no value is passed, it returns a copy of the original array.
const array1_2 = arr1.map( val => val ); // so this one simply returns the value for each member of the array, creating a copy of the original.

There are other ways to copy an array, but these will get you the idea - you need to manually create a new copy of the array, or it will be passed by reference, rather than by value.

The same holds true for objects - these are also passed by reference. If I did

const playerOne = {
  name: {
    first: 'Bobby',
    last: 'Johnson'
  },
  userName: 'boJoGoGo',
  hiScores: [
    {
      game: 'Klondike',
      score: 2325
    },{
      game: 'Minesweeper',
      score: 3
    }
  ]
};
// The above is an object - but what is its value?

const playerTwo = playerOne;
// The above assigns playerTwo to the same memory space currently held by playerOne...
//  So they are, in fact, the same thing!

playerTwo.name.first = 'Timmy';
// What do you think happens if we do the above line? Would that effect playerOne?

The same problem applies - the only variables passed by value are primitives (String, Number, Boolean, null, undefined and the less common BigInt and Symbol). Arrays and Objects are passed by reference! So how can we ‘clone’ an object? Again, there are a few ways, but my personal favorite is to use JSON (Javascript Object Notation):

const playerTwo = JSON.parse(JSON.stringify(playerOne) );
// so the stringify turns the object into a string, then the parse turns it BACK to a new object!

Same thing, though, there are always other ways to do the same thing.

Long and short of it, you need to copy (or clone) your arrays, what you’re doing now is simply pointing to and using the original.

Sorry I got long-winded, but I truly hope this helps.

You are a saint! This is a huge help. I know that using loops was inefficient for this exercise; I like solving these problems with multiple methods so gave it a shot anyway.

1 Like