从过滤器方法javascript返回索引值

时间:2014-10-20 14:50:22

标签: javascript angularjs

所以我的角度控制器中有一个对象数组,我想返回数组中字段索引的值,该数组与我的参数具有匹配的ID。数组中只有一个对象具有匹配的fieldId ..

$scope.indexOfField = function(fieldId) {
        return $scope.model.fieldData.filter(function(x) {
            if (x.Id === fieldId) {
                return // ???????
            }
        });
    }

13 个答案:

答案 0 :(得分:12)

来自Array.prototype.filter文档:

  

使用三个参数调用回调:

     
      
  • 元素的值
  •   
  • 元素的索引
  •   
  • 正在遍历的Array对象
  •   

但是,如果数组中只有一个实例(因为它会在找到第一个匹配项后立即停止),您可能应该使用some函数,然后使用{{1}找到索引}:

indexOf

或者迭代数组,直到找到正确的元素:

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

答案 1 :(得分:10)

您无法从过滤方法返回索引。

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

您可以使用forEach

filter()方法创建一个新数组,其中包含通过所提供函数实现的测试的所有元素。

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

甚至更好地使用for,因为当您找到自己的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
    }

答案 2 :(得分:4)

回调的第二个参数是索引。我无法确定您希望函数执行/返回的内容,但如果在, index之后添加function(x,则可以访问该迭代的索引。

使用您的函数的名称,我认为您根本不需要filter

$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在第一次迭代时停止,返回真值,因此我们会在第一次找到匹配时停止搜索。

答案 3 :(得分:2)

数组(查找多个索引)方法

emission

否则,您会得到...

emission = emission[::-1, :]

返回多个索引(代替findIndex方法)

[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)

返回多个值(代替查找方法)

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

答案 4 :(得分:1)

使用findIndex。 您可以使用此功能。首先满足条件时,将返回索引。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex

答案 5 :(得分:1)

尝试带有或不带有i的flatMap。

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

答案 6 :(得分:0)

某些语言可以map一个集合到索引集合中,其中每个元素都映射到一对{element, index}。这样你就可以使用这两个值中的任何一个映射/过滤/等。

例如,Kotlin有withIndex而Swift有enumerated

Javascript没有这种方法,AFAIK。但您可以轻松构建自己的或使用变通方法。

解决方法(不推荐)

// 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 => x.v.id == fieldId)[0].i

withIndex方法添加到Array(推荐):

这与解决方法基本相同,但创建了一个可重用的功能,使其更加清晰。

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}`);
}

答案 7 :(得分:0)

findIndex方法返回满足函数给定条件的数组第一个元素的索引。如果函数对数组的所有元素返回false,则结果为-1。

请参阅文档here
在我的示例中,x是每次迭代的一个项目,我对条件使用交叉函数。

希望我能帮助您

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

答案 8 :(得分:0)

您不能直接返回索引,但是可以设置'thisArg' parameter并在其中设置数据。这比全局变量更干净。

df <- structure(list(Features = structure(c(1L, 11L, 12L, 13L, 14L, 
15L, 16L, 17L, 18L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L), .Label = c("Var1", 
"Var10", "Var11", "Var12", "Var13", "Var14", "Var15", "Var16", 
"Var17", "Var18", "Var2", "Var3", "Var4", "Var5", "Var6", "Var7", 
"Var8", "Var9"), class = "factor"), Column1 = c(0L, 0L, 0L, 0L, 
0L, 0L, 1L, 1L, 1L, 1L, 1L, 0L, 0L, -1L, -1L, -1L, 0L, 0L), Column2 = c(0L, 
0L, 0L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, -2L, -2L, -2L, -2L, -2L, 
0L, 0L), Column3 = c(0L, 0L, 0L, 0L, 2L, 2L, 2L, 2L, 2L, 2L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Column4 = c(0L, 0L, 0L, 2L, 
2L, 2L, 2L, 0L, 0L, 0L, 0L, 0L, -2L, -2L, -2L, -2L, 0L, 0L), 
    Column5 = c(0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 0L, 0L, 0L, 0L, 0L), Column6 = c(0L, 0L, 0L, 2L, 2L, 
    2L, 0L, 0L, -1L, -1L, -1L, -1L, -1L, -1L, 0L, 0L, 0L, 0L), 
    Column7 = c(-1L, -1L, 2L, 2L, 2L, 2L, 2L, 2L, -1L, -1L, -1L, 
    -1L, -1L, -1L, -1L, -1L, -1L, -1L), Column8 = c(1L, 1L, 1L, 
    1L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 1L
    )), class = "data.frame", row.names = c(NA, -18L))

答案 9 :(得分:0)

如果仅返回一个对象,则可以简单地使用原始数组引用返回的对象。

由于过滤器返回数组,因此您可以执行以下操作

$scope.indexOfField = function(fieldId) {
    var filteredArray = $scope.model.fieldData.filter(function(x) {
        return x.Id === fieldId
    });

    var desiredObject = filteredArray[0]
    return $scope.model.fieldData.indexOf(desiredObject);
}

答案 10 :(得分:-1)

过滤器不会返回索引,但你可以这样做。

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

答案 11 :(得分:-1)

function modifyArray(nums) {
let newNums = nums.filter((num,index) => {
        return num = num % 2 ? num * 3 : num * 2; 
    })
  return newNums;
}

此处索引是您要查找的增量值。

答案 12 :(得分:-1)

$scope.indexOfField = function(fieldId) {
  let index;
  $scope.model.fieldData.filter((x, i) => {
    if (x.Id === fieldId) index = i;
    return x.Id === fieldId;
  });
  return index;
}