Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return index value from filter method javascript

The .findIndex() method returns the index of the first element of the array that satisfies a condition given by a function. If the function returns false for all elements of the array, the result is -1.

See the documentation here.

In my example, x is an item for each iteration and I use cross function for my condition.

const datas = [];
const fieldId = 5;
let index = datas.findIndex( x => x.Id === fieldId );

You can't return index from filter method.

The filter() method creates a new array with all elements that pass the test implemented by the provided function.

You can use forEach

$scope.indexOfField = function(fieldId) {
    var i;
    return $scope.model.fieldData.forEach(function(x, index) {
        if (x.Id === fieldId) {
            i = index;
        }
    });
    // use i
}

or even better to use for as you can't stop forEach when you have found your id.

$scope.indexOfField = function(fieldId) {
    var fieldData = $scope.model.fieldData, 
        i = 0, ii = $scope.model.fieldData.length;
    for(i; i < ii; i++) if(fieldData[i].Id === fieldId) break;
    // use i
}

From the Array.prototype.filter documentation:

callback is invoked with three arguments:

  • the value of the element
  • the index of the element
  • the Array object being traversed

However you should probably be using the some function if there is only one instance in your array (as it will stop as soon as it finds the first occurrence), and then find the index using indexOf:

var field = $scope.model.fieldData.filter(function(x) {
    return x.Id === fieldId;
})[0];
var index = $scope.model.fieldData.indexOf(field);

Or iterate the array until you find the correct element:

var index;
$scope.model.fieldData.some(function(x, i) {
    if (x.Id === fieldId) return (index = i);
});

ARRAY (FIND MULTIPLE INDEXES) METHOD

[10, 7, 13, 15, 230].map((e,i) => e > 13 ? i : undefined).filter(x => x) 
      //returns [3, 4](*** RETURNS multiple indexes ***)
      //FILTER (is simply just REMOVING the UNDEFINED elements (which are FALSY and considered the same as FALSE)

otherwise you'll get...

[10, 7, 13, 15, 230].map((e,i) => e > 13 ? i : undefined)  //returns [undefined, undefined, undefined, 3, 4]

RETURN MULTIPLE INDEXES (replaces findIndex METHOD)

[1, 1, 2, 2, 2, 3, 4, 5].map((e,i) => e === 2 ? i : undefined).filter(x => x) //returns [2, 3, 4]

RETURN MULTIPLE VALUES (replaces find METHOD)

[5, 12, 8, 130, 44].map((e,i) => e > 13 ? e : undefined).filter(x => x) // returns [130, 44]

The second argument to your callback is the index. I can't quite make out what you want your function to do/return, but if you add , index after function(x, that will give you access to the index for that iteration.

Working from the name of your function, I don't think you want filter at all:

$scope.indexOfField = function(fieldId) {
    var result = -1;
    $scope.model.fieldData.some(function(x, index) {
        if (x.Id === fieldId) {
            result = index;
            return true;
        }
    });
    return result;
}

Array#some stops as of the first iteration that returns a truthy value, so we'll stop searching the first time we find a match.


You cannot return directly the index but you can set the 'thisArg' parameter and set data inside it. This is cleaner than a global variable.

var data = {
    indexes: []
};
var myArray = [1,2,3,4,5,6,7,8,9,10];

myArray.filter(function (element, index) {
    if (element%2 == 0) {
        this.indexes.push(index);
        return true;
    }
}, data);

console.log(data.indexes); // [1, 3, 5, 7, 9]
data.indexes.forEach(function(value) {
    console.log(myArray[value]);
}); // 2, 4, 6, 8, 10