0

I understand that there are ways to get unique elements in an array. This question isn't asking about that. This question is asking why indexOf returns -1 for "kale" in the unique_vegetables array once it's already been added. Is there something about indexOf that makes it not work in this situation?

    var vegetables = ["kale", "broccoli", "kale"];

    function produce(){
       var unique_vegetables = [];
       unique_vegetables = vegetables.map(function(v){
        if (v.length > 0){  //irrelevant check to make sure the string has characters
             var k = unique_vegetables.indexOf(v);
            return k < 0 ? v : null;
        }else {
             return null;
        }
       })
       return unique_vegetables;
    }

    var t = produce();
    console.log(t, "unique vegetables")  ///  ["kale", "broccoli", "kale"]

https://jsfiddle.net/mjmitche/g6nn9nn6/

Leahcim
  • 40,649
  • 59
  • 195
  • 334
  • Why dont you *filter*? – Jonas Wilms Jun 15 '17 at 13:06
  • 1
    _why indexOf returns -1_, because `unique_vegetables` is `[]` just put a console – Satpal Jun 15 '17 at 13:07
  • Because `v.length > 0` is true always and `unique_vegetables.indexOf(v)` is always `-1` as array is empty. So you are returning same value. Are you trying to achieve [this](https://jsfiddle.net/RajeshDixit/g6nn9nn6/1/)? – Rajesh Jun 15 '17 at 13:07
  • @Satpal but is unique_vegetables still [] when the second instance of "kale" maps? – Leahcim Jun 15 '17 at 13:09
  • @Leahcim Yes. `unique_vegetables` will be updated when `.map` returns the value. You are returning from `Callback` to `.map` – Rajesh Jun 15 '17 at 13:10
  • Possible duplicate of [Unique values in an array](https://stackoverflow.com/questions/1960473/unique-values-in-an-array) – cmbuckley Jun 15 '17 at 13:14

2 Answers2

2

When you are using Array.map, there are 3 things that make it a whole.

  • Callback function
  • Return statement inside callback
  • Return from .map

Callback is the function that will be called on every iteration and will be passed 3 arguments viz., currentElement, index, and array itself.

Return from callback will initialize the value of this iteration in return array. This return array is a local array in .map and will not be accessible to you.

Return from map is the final step that returns the parsed local array pointed out in previous step.

Array.map would look something like this in simple implementation:

function myMap(arr, callback){
  var temp = [];
  for(var i = 0; i< arr.length; i++){
    temp[i] = callback(arr[i], i, arr);
  }
  return temp;
}

var a = [1,2,3,4,5];
var b = myMap(a, function(n, i, a){ return n * 2 })
console.log(b)

Reference

Community
  • 1
  • 1
Rajesh
  • 24,354
  • 5
  • 48
  • 79
0
vegetables.forEach(function(v){
    if (v.length > 0){ 
         var k = unique_vegetables.indexOf(v);
        if(k < 0) unique_vegetables.push(v);
    }
})

unique_vegetables is an empty array until the map function finished and returned, so you need to change unique_vegetables while iterating.

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151