1

I am trying to remove duplicate items from a collection that I request via an API in Laravel.

This is my code:

computed: {
      // slice the array of data to display

      filteredList() {

        /* NEW PART */


            var tips = this.dublicate;

            /* END NEW PART */



          tips = this.items.filter(item => {
            return item.tip.toLowerCase().includes(this.search.toLowerCase())
          })
          return tips.slice(0, this.display);

      },

      dublicate() {

        var filtered_array = [];
        for(var i =0; i < this.items.length; i++) {
            if(this.items[i].tip.toLowerCase() != this.items[i+1].tip.toLowerCase()) {
              filtered_array.push(this.items[i])
            }
        }
        return filtered_array;
      }
   }
   }

If I remove the code within the NEW PART comments, everythin works fine. In the NEW PART I am trying to remove duplicate content, based on the items tip attribute. If the tip attribute is the same as the next items tip attribute, it should be excluded from the tips array, which is returned as a v-for="tips in filteredList".

However, I just get an empty array with this new part. What am I doing wrong?

I get the following from Vue Devtools:

dublicate:"(error during evaluation)"
filteredList:"(error during evaluation)"

An example data from items, that are from an API request:

enter image description here

(This is the data that I get, when I dont try to remove duplicates, which works)

As this is in VueJS, I cant use the answer provided here.

PJJ
  • 87
  • 2
  • 14
  • Possible duplicate of [Remove duplicate values from JS array](https://stackoverflow.com/questions/9229645/remove-duplicate-values-from-js-array) – smarber Jan 05 '18 at 11:17
  • You're defining `tips` as a function, not as the result of a function call. – Roy J Jan 05 '18 at 12:54
  • Hi @RoyJ I have updated my question, as this is now a result of a function call. Still not working though :/ – PJJ Jan 05 '18 at 13:15
  • Can you include a sample of data for `items`? – Roy J Jan 05 '18 at 13:22
  • Oh, if `dublicate` is a computed, you can't call it as a function. The line should be `tips = this.duplicate` – Roy J Jan 05 '18 at 13:23
  • Hi @RoyJ - Thanks for your input. Ive changed the function call to `this.duplicate`, and included some sample data in my question. However I still can not get it to work, and I get `(error during evaluation)` – PJJ Jan 05 '18 at 13:31
  • If you are using something like Lodash, they have a `uniq()` that will return duplicate free arrays – ggdx Jan 05 '18 at 14:26
  • 1
    `i + 1` goes beyond the array – Roy J Jan 05 '18 at 16:50

1 Answers1

3

You are looking past the end of the array with i + 1. You need to push the last item without looking for the one after it (because there isn't one). I think using filter is more straightforward than building an array with a for loop.

dublicate() {
  return this.items.filter((a, i) =>
    i === this.items.length - 1 ||
    a.tip.toLowerCase() !== this.items[i + 1].tip.toLowerCase()
  );
}
Roy J
  • 42,522
  • 10
  • 78
  • 102
  • Hi Roy, I will be testing tomorrow and will return with an acceptet answer if this works :) Thanks for your input and support! – Patrick Jan 07 '18 at 17:42
  • Hi Roy, yep this worked right out of the box! Thank you! If you have time, I would like it if you could help me clarify some things about the code. Im not entirely sure what the function does. The filter function has a & i, and a is the items? What does `i === 0 ||` mean? And the filter goes through all the items, and checks if a tip is not equal to the next, and then pushes it into the duplicate array that can then be used as a `v-for`, is the correctly understood? – PJJ Jan 08 '18 at 07:20
  • `i` is the index, and `a` is the item. `i === 0` means you're looking at the first item. It keeps each item that is not equal to the *previous* item. The test for zero is because there is no previous item for that one. – Roy J Jan 08 '18 at 11:34
  • I have just updated the code to keep items that differ from the *next* item. If looking at the last item, it keeps it and does not try to look at item `i + 1` (due to `||` short-circuiting). – Roy J Jan 08 '18 at 11:54