Lodash project : invert lesson

Hello, I’m still working on the Lodash lesson and down to step 25.

Assuming that the object parameter is in a similar format to that which was outlined in this post
var object = { ‘a’: 1, ‘b’: 2, ‘c’: 1 };
When finished, the output should look like:
{1: ‘a’, 2: ‘b’ 1: ‘c’}

Given the above, this is what I came up with after reviewing other posts and reviewing my copious notes from prior lessons:

// step 23 - 26 .invert method
  	invert(object){
      const invertedObject = {}
      for(let key in object){
      	const originalValue = object[key]
        object[key] = object[value]
        object[value] = originalValue
        //invertedObject = {originalValue: key}
      }
      return invertedObject
    }//closes the invert method

I can’t figure out how to ‘grab’ the key Vs value from the combined property. Looking at another student’s work posted on this forum, I copied object[key] assuming that this allows me to grab the key of the object. I probably wrongly assumed that object[value] is the way to get the corresponding value. I have no idea why const invertedObject={} had to be added to the code.

Also, I saw that mtf used invertedObject = {originalValue: key} in this post, which introduced more strange syntax to me that I just don’t recall ever seeing and can’t find in my notes.

I’m embarrassed to say that I’m just completely lost. Probably before I attempt to figure out this lesson, I need to be sent off to review a past lesson to refresh my memory…

Thank you for your insight.

1 Like

You spend enough time on google and stackoverflow and eventually you find something that looks similar to what you’re trying to do. Stackoverflow even lists a jsfiddle.net link to see it work.

I modified my code above to work as shown in the above stackoverflow link and tried it out on jsfiddle:

const objectValues = {A : 1, B : 2, C : 3, D : 4}

const invert = (object) => {
      const invertedObject = {}
      for(let key in object){
        invertedObject[object[key]] = key;
      }
      return invertedObject
    }//closes the invert method

console.log(invert(objectValues))

The above worked. I removed the function stuff which left me with the code to create the method I needed to complete this project:

invert (object) {
      const invertedObject = {}
      for(let key in object){
        invertedObject[object[key]] = key;
      }
      return invertedObject
    }//closes the invert method

Passed the test!

$ node test/invert.js
_.invert() Tests:
1 - _.invert() is defined - Passed!
2 - Returns an object with all keys and values inverted
 - Passed!
3 - Returns an object with all keys and values inverted
 - Passed!
$

What is a bit disconcerting for me is that the above doesn’t follow the step 25 bullet 5 directions regarding the creation of a variable called originalValue.

Can anyone explain in detail what this line of code is doing?
invertedObject[object[key]] = key; How does the ‘key’ get flipped to ‘value’ and visa versa?

I would really appreciate it.

1 Like

I don’t see anything (other than how the loop operates on objects) that might be new to you there. It’s just getting and setting attributes, and object literals.

Your first shown version modifies the original instead of the new object that you’re supposed to create, that must surely come from not having decided on what should happen in the first place which is “here’s my new empty object, let’s copy everything over, except with flipped keyvalue pairs” which in turn tells you that you need to obtain all key value pairs, which is an easy first thing to get done and observe with console.log, and then add them to the new object.

What is an object? It’s a key value store. What can you do with it? You can get by key. You can set by key. That’s pretty much it, and it’s also all you need to do here, plus the loop over keys.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects

Thanks for the link, it was great review. I’ll have to review it again later i’m sure.

In searching the web, I learned that this code:
invertedObject[object[key]] = key;
basically says that the key becomes the value within each property. I still can’t comprehend how the value becomes the key. Regardless, I’m moving onto the next lesson. I’ll hope to revisit this again later.

invertedObject[object[key]] = key;
Is these:

object[key]
object[key] = value

both of which you should know what they do and which you should be able to tell that they’re in there. It’s just one action after the other, isn’t it?
There’s certainly no special interaction just because they’re written on the same line, it’s not new.

Those are very basic actions, get them figured out. They’re somewhere in the the first third or so of that document I linked. They’re just get and set.

If it helps, rewrite it so that rather doing them on the same line, assign a variable to the result of the first action and then use that variable in the second.

Hi ionatan,

I keep re-reading that page and I can’t see how this invertedObject[object[key]] = key; is related to a getter or setter so, I pulled it out of my code and decided to go back and follow the directions by including the originalValue variable. The jsFiddle.net web site BTW is enormously helpful.

const objectValues = {A : 1, B : 2, C : 3, D : 4}
console.log(objectValues) // prints out {A: 1, B: 2, C: 3, D: 4} 

const invert = (object) => {
      let invertedObject = {}
      for(let key in object){
        //console.log(key) // prints out the keys A, B, C, D
        //console.log(object[key]) // prints out the values 1, 2, 3, 4 
        let originalValue = object[key]
        //console.log(originalValue) // prints out the values 1, 2, 3, 4  this is good.
        //invertedObject = {originalValue: key} //THIS IS THE PROBLEM!!!
        invertedObject.push({originalValue: key})  //THIS DOESN'T WORK EITHER
        console.log(invertedObject) //prints out {originalValue: "A"} //etc.
      }
    }//closes the invert method

invert(objectValues)

There are two problems with using the line invertedObject = {originalValue: key}

  1. Instead of getting 1: ‘A’, 2: ‘B’, 3: ‘C’, 4: ‘D’, I get {originalValue: “A”}, etc for each letter and they don’t append the object, they overwrite the prior value in invertedObject which leads to problem 2).
  2. Although that page you sent me to is very helpful, all of the examples seem to create new objects and don’t append objects (or I overlooked it). This issue let me to a page on stackoverflow which suggests I use the ‘push’ method.

If you toss the above into jsfiddle you’ll notice that the console barks about invertedObject.push not being a function.

Yeah so I’m stuck again. I wonder what the record is for the number of hours spent this one lesson. :slight_smile:

Note that we cannot redefine with let in a loop. Define it outside of the loop.

let originalValue;

As you have discovered, there is no push method for objects.

objects can get and set values by key. that’s the whole point of objects.

You iterate through keys of the original object. You obtain the corresponding values. Then you set each such keyvalue pair on the new object, except switching the key and value.

Modifying an existing object doesn’t cause other attributes in it to be wiped. In other words you’re replacing the whole object.
How do you modify an existing object? Is that what you’re doing in your code? (clearly not)

// create empty object
stuff = {}
// modifying it by setting 'aoeu' to 5
stuff['aoeu'] = 5
// modifying it by setting 'nsth' to 7 (do you expect 'aoeu' to get wiped? no.)
stuff['nsth'] = 7
// get by key 'aoeu'
console.log(stuff['aoeu'])

Never mind this lesson, this is the first thing you learn about objects.

You don’t have an ‘push’ property, you did not set that, so, no, you can’t use it. Objects don’t support that. They support get, and set, and that’s nearly all they ever do.

As for getting originalValue, why would you use ‘originalValue’ as the key? You took a variable name, and turned it into a string, you need better control than that over what you’re writing.
If you want the key ‘Z’ to be associated with the value ‘97’, then you should certainly not end up with the key ‘originalValue’ in the object. The key you should have added is ‘Z’


The exercise tells you how to iterate over keys.
Given a key, can you get the corresponding value?
Does that mean you can obtain each key value pair?
Since you have the key and the value, which one is the new key and the new value?
Modify the new object by adding the new key and value to it.

^ nothing new in there.

And, please stop copying things. Decide what operations should happen, and write those.

The stack overflow post you linked to does not suggest pushing to an object.
The question also doesn’t match the problem, nor does the question even really make sense, since appending isn’t something you do to an object, appending is something you do to a list or an array, and that is also the suggestion that the answer there makes, that if append is wanted, to use a data structure that supports appending.


How about, you open an empty file, create a variable and let it refer to an empty object.
Then figure out how to set an attribute on it, and print the result.
Because that’s really all there is here, isn’t it.

Or, set yourself another exercise to complete.
For example, given a string, count the number of times each character appears.
For the string ‘aaab’, I should be able to look up ‘a’ in the result and get 3, or ‘b’ and get 1
An object lets you store the counts. The only operations on the object you need are get and set so that you can read current counts, and update them.

Hi mtf & ionatan,

I got this project working. Interesting that it works with originalValue when it is defined in or outside the loop. Odd?

const objectValues = {A : 1, B : 2, C : 3, D : 4}
console.log(objectValues) // prints out {A: 1, B: 2, C: 3, D: 4} 
const invert = (object) => {
	let invertedObject = {}
	//let originalValue; // works outside or insdie the for loop
    for(let key in object){
      let originalValue; // per 'mtf' this should be above for loop but, it works
      invertedObject[object[key]] = key
    }
    return invertedObject
  }
console.log(invert(objectValues))

ionatan, thank you big for the tip!!!
invertedObject[object[key]] = key did the trick. I’m still wrapping my head around why it works but, it works and I’m grateful to you guys. I feel so incredibly overwhelmed and glad that i stuck to it.

I owe you guys!

Mike

1 Like

You’re not using it, you can remove it, where you put it has no effect.

ionatan, geez, you are correct. Are you shaking your head in amazement at how clueless I am at times? I’m sorry.

Looking back, I actually have the same code that worked in my 2nd post that starts with 'You spend enough time on google '. The goodnews is that I feel like I understand much more. I didn’t follow the directions exactly but, it works and you guys were a huge help. I can’t do this stuff without your assistance. Very grateful…

1 Like

…But you might want to use it, because it avoids nesting things when you modify the inverted object

Storing intermediary results in variables can sometimes go a long way to making code simpler

We might find it does not when put to use. To be clear.

let invertedObject = {};
let originalValue;
for (let key in object) {
    originalValue = object[key];
    // other update
}

In other words, declare before, set during the loop (if you are going to use an intermediary variable).

It’s only used inside that scope, it doesn’t need to exist outside it

I’m at odds with let in the loop. Perhaps I’m misguided?

Not sure what your argument is for putting it outside.
Maybe you mean var which has a different life span, but that still wouldn’t need to be moved into the parent scope (linters might complain though)

Ah ha.

invertedObject[object[key]] = key; is the same as invertedObject[originalValue] = key; original value holds value from current key which is assigned first in the loop: let originalValue = object[key];. Lets says you had an object like this:

const employees = {
    boss: 'Michael',
    secretary: 'Pam',
    sales: 'Jim',
    accountant: 'Oscar'
};

to add new key/value pair you the object, you would have 2 options either dot notation or bracket. employees.isRch = true or employees['isRich] = true . This will add new key/value pair to obj and would look like this:

const employees = {
    boss: 'Michael',
    isRich: true,
    secretary: 'Pam',
    sales: 'Jim',
    accountant: 'Oscar'
};

Therefore invertedObject[object[key]] = key is just assigning key/value pair to invertedObject. I hope that makes sense and its helpful. I was also stuck and your code helped connect the dots. happy coding