Index return value from javascript filtering method

So, I have an array of objects in my angular controller, and I want to return the index value of the field inside the array that has the corresponding identifier to my parameter . There will be only one object in the array with a suitable fieldId ..

$scope.indexOfField = function(fieldId) { return $scope.model.fieldData.filter(function(x) { if (x.Id === fieldId) { return // ??????? } }); } 
+15
source share
9 answers

You cannot return an index from a 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

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

 $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 , because you cannot stop forEach when you find your identifier.

 $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 } 
+10
source

From the documentation of Array.prototype.filter :

The callback is called with three arguments:

  • item cost
  • item index
  • array object passed

However, you should probably use the some function if there is only one instance in your array (since it will stop as soon as it detects 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); }); 
+11
source

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

Working with the name of your function, I don't think you want a 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 at the first iteration, which returns a true value, so we will stop searching the first time we find a match.

+4
source

ARRAY METHOD (FIND MULTIPLE INDICES)

 [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 get ...

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

RETURN SEVERAL INDEXES (replaces the 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 SEVERAL VALUES (replaces METHOD method)

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

Some languages ​​may map collection into an indexed collection, where each element is mapped to a pair of {element, index} . This way you can display / filter / etc using either of these two values.

For example, Kotlin has withIndex, and Swift has listed .

Javascript does not have such a method, AFAIK. But you can easily create your own or use a workaround.

Workaround (not recommended)

 // Turn an array of elements into an array of {value, index} const indexedArray = array.map((v,i) => ({value:v, index:i})); // Now I can filter by the elem but keep the index in the result const found = array.filter(x => x.value === someValue)[0]; if (found) { console.log('${found.value} found at index ${found.index}'); } // One-liner for the question scenario, using some new js features. // Note that this will fail at the last ".i" if the object is not found. const index = fieldData.map((v,i) => ({v,i})).filter(x => xvid == fieldId)[0].i 

Add the withIndex method to Array (recommended):

Essentially, this is the same as a workaround, but creating a reusable function that makes it a lot cleaner.

 Array.prototype.withIndex = function() { return this.map((v,i) => ({value: v, index: i})) }; // Now the one-liner would be: const index = fieldData.withIndex().filter(x => x.value.id == fieldId)[0].index; // Better, with null checking: const found = fieldData.withIndex().filter(x => x.value.id == fieldId)[0]; if (found) { console.log('${found.value} found at index ${found.index}'); } 
0
source

The findIndex method returns the index of the first element of the array that satisfies the condition specified by the function. If the function returns false for all elements of the array, the result will be -1.

See documentation here
In my example, x is an element for each iteration, and I use a cross function for my condition.

I hope to help you

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

You cannot directly return the index, but you can set the thisArg parameter and set the data inside it. It 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 
0
source
 function modifyArray(nums) { let newNums = nums.filter((num,index) => { return num = num % 2 ? num * 3 : num * 2; }) return newNums; } 

Here the index is the increment value you are looking for.

0
source

The filter will not return the index, but you can do something like this.

 $scope.indexOfField = function(fieldId) { $scope.model.fieldData.filter(function(x, i) { if (x.Id === fieldId) { var indexOfField = i; } }); return indexOfField; }; 
-1
source

Source: https://habr.com/ru/post/1205105/


All Articles