How to remove every other repeated word

an array or an object: you need to keep the three numbers separated, and you can do that or in an array with the same indexes, or in an object using the words as property names…

Ok… I want to do it with an object.

So how do i store the info taken from filtering the betterWords array in the object?

And then how would i know how to search in the object to know which words i should remove?

if you create an object like { really: 0, very: 0, basically: 0} , you can access the numbers using the word itself
but you need to create it outside filter, as you had the count variables outside filter

1 Like

That’s what i did now, but I don’t know how to store info coming from filtering in the object

let overusedWordsCount = {};
  overusedWordsCount['really'] = 0;
  overusedWordsCount['very'] = 0;
  overusedWordsCount['basically'] = 0;

let count = 0;

const removeEveryOtherWord = betterWords.filter(word => {
  let index = overusedWords.indexOf(word);
  if(index < 0) {
    return true;
  } else {
    overusedWordsCount ++;
    if (count % 2 != 0) {
      return true;
    }
  }
});

overusedWordsCount is not a number so you can’t do this, instead how do you access the numbers inside an object, do you remember? You already did when setting up the object.
Now you need to do that with a variable.

Ok Ok this is being of great help… I’m getting there:

let overusedWordsCount = {};
  overusedWordsCount['really'] = 0;
  overusedWordsCount['very'] = 0;
  overusedWordsCount['basically'] = 0;


let count = 0;

const removeEveryOtherWord = betterWords.filter(word => {
  let index = overusedWords.indexOf(word);
  if(index < 0) {
    return true;
  } else {
    overusedWordsCount[word]++;
  }
});

// return { really: 2, very: 5, basically: 1 }

So how would i select now the words i want to delete? Like this?

let overusedWordsCount = {};
  overusedWordsCount['really'] = 0;
  overusedWordsCount['very'] = 0;
  overusedWordsCount['basically'] = 0;

const removeEveryOtherWord = betterWords.filter(word => {
  let index = overusedWords.indexOf(word);
  if(index < 0) {
    return true;
  } else {
    overusedWordsCount[word]++;
    if(overusedWordsCount[word] % 2 != 0) {
      return true;
    }
  }
});

remember that filter keeps an element (a word) if it returns true (or a trurhy value), and doesn’t keep it if it returns false or a falsy value

when should you return true and when false?

with if(index < 0) { return true; } you have just said “if it is not an overused word keep it”

(if you do not return anything it default to returning undefined, which is falsy, and means that the word is not kept)

I should keep all the words that are not in the overusedWords array and then from the overusedWords, delete every other one of EACH one of them.

So basically i could do this too right??

let overusedWordsCount = {};
  overusedWordsCount['really'] = 0;
  overusedWordsCount['very'] = 0;
  overusedWordsCount['basically'] = 0;

const removeEveryOtherWord = betterWords.filter(word => {
  if(!overusedWords.includes(word)) {
    return true;
  } else {
    overusedWordsCount[word]++;
    if(overusedWordsCount[word] % 2 != 0) {
      return true;
    }
  }
});

yes, if it works, that’s pretty good

my idea with indexOf was if you wanted to use an array to store the numbers, with an object you are right, includes works pretty well

and in case it ended that you had to remove each second overusedWords, you can make some small tweaks and it will work

I imagine you will need to make it again a string later, or not?

also, the name removeEveryOtherWord is confusing, as filter returs an array without every other word already: it seems confusing to have an array already without those words being called removeEveryOtherWord

1 Like

Aww I see, indexOf would indeed be better in case i’d use an array to store the info…
As i’ve never worked with this kind of objects, I’m happy you helped me figuring out how to do that, honestly that was of great help!

The exercise doesn’t really specify that i would have to make it a string but it’s a good idea and i like it. Should i just .join() the words in the filtered array??

And i kind of get what you said about the name of the function, but shouldn’t it be called as the action it’s supposed to do? (How would you call it?)

I’m just asking out of curiosity, You’ve been a HUGE help for me today… honestly. :grin:

Thank you!

but that’s not the name of the function, that’s the name you are giving to the array returned from filter: as filter returns an array, you are then storing it inside removeEveryOtherWord, which is actually a name more suited for the callback of filter

you could do something like:

const removeEveryOtherWord = word => {
  if(!overusedWords.includes(word)) {
    return true;
  } else {
    overusedWordsCount[word]++;
    if(overusedWordsCount[word] % 2 != 0) {
      return true;
    }
  }
};

const newArr = betterWords.filter(removeEveryOtherWord);
// I will let you find a good descriptive name for this one

sure, just be careful on choosing the appropriate argument.

I guess I’d have to use a space as the argument…

I’ve got another question… What if I were to add a word in the overusedWords array and I wanted my function to work anyway without making any more changes?

Basically, how would I keep track of the overusedWords in my object without naming the words as properties of the object?

Any idea of how could I approach that matter?

you could create dinamically the object you use to count

this part, instead of hardcoding the property names, you do it with the elements from the array - how do you repeat the same code once for each element inside an array?

I can only think of this but it’s wrong…

let overusedWordsCount = {};

  overusedWordsCount[overusedWords.forEach(word => {

    return word = 0;

  })];

you can use forEach, but not like that

you can think of forEach as doing exactly the same thing as a loop, repeating the same piece of code for each element of an array
forEach returns undefined, you can’t put it inside the square parenthesis

also the inside of the square parenthesis is evaluated to a single value, so in that way you are just doing it for one single property of overusedWordsCount

first, how do you access an object property with a variable?

second, where that variable should come from, if it should be each time a different string from the array?
remember that you need to use the assignment operator to give the starting value
exactly as here:

but with a variable inside the square parentheses

I’m trying but i can only come up with this (which is wrong too):

const overusedWordsCount = {overusedWords.forEach(word => {
  return overusedWordsCount[word] = 0;
});}

I don’t really know where i should declare the object and to reference all of the words in the overusedWords array in the object… As i said this is the first time I’m working with this kind of objects and properties :sweat_smile:

I guess I’ve got to declare a variable outside the object and then pass it as the object property right?

ok, no, you can’t do that

you have written const overusedWordsCount = {undefined}

forEach returns undefined, so you can’t assign forEach to something

first, let’s take what you wrote before:

let overusedWordsCount = {};
  overusedWordsCount['really'] = 0;
  overusedWordsCount['very'] = 0;
  overusedWordsCount['basically'] = 0;

now, let’s move from hardcoding values, to using the elements of the array:

let overusedWordsCount = {};
  overusedWordsCount[overusedWords[0]] = 0;
  overusedWordsCount[overusedWords[1]] = 0;
  overusedWordsCount[overusedWords[2]] = 0;

let’s see if looking at it in this way you can see it better what needs to be iterated over

I understand I’ve to interate through the indexes of overusedWords array and put that in a variable. And that variable would be the property of the overusedWordsCount object if I’m not mistaken.

The thing I don’t understand is, where and how would i use forEach in order to achieve that. Plus it has to ve a variable, not a function…

I don’t know I just don’t get it… But at the same time i don’t want you tell me the solution. :sweat_smile:

forEach will iterates through the elements of an array and do something for each of them
so, you could do overusedWords.forEach(overuserWord => /* do something with the overusedWord */ )

Great I think I’ve got it right now… I kind of did something similar before but maybe misplaced it or something.

What do you think about this?

let overusedWordsCount = {};
let index = overusedWords.forEach(overusedWord => {
  overusedWordsCount[overusedWord] = 0;
});

const arrayWithRemovedWords = betterWords.filter(word => {
  if(!overusedWords.includes(word)) {
    return true;
  } else {
    overusedWordsCount[word]++;
    if(overusedWordsCount[word] % 2 != 0) {
      return true;
    } else {
      return false;
    }
  }
});

BTW why I don’t have to mention ‘index’ anywhere else for it to work?