我想知道是否有一个已知的,内置/优雅的方法来找到一个JS数组的第一个元素匹配给定的条件。c#的等效程序是List.Find。

到目前为止,我一直在使用这样的双功能组合:

// Returns the first element of an array that satisfies given predicate
Array.prototype.findFirst = function (predicateCallback) {
    if (typeof predicateCallback !== 'function') {
        return undefined;
    }

    for (var i = 0; i < arr.length; i++) {
        if (i in this && predicateCallback(this[i])) return this[i];
    }

    return undefined;
};

// Check if element is not undefined && not null
isNotNullNorUndefined = function (o) {
    return (typeof (o) !== 'undefined' && o !== null);
};

然后我可以用:

var result = someArray.findFirst(isNotNullNorUndefined);

但既然ECMAScript中有这么多函数风格的数组方法,也许已经有这样的东西了?我想很多人都必须实现这样的东西……


当前回答

foundElement = myArray[myArray.findIndex(element => //condition here)];

其他回答

简介:

为了找到数组中第一个符合布尔条件的元素,我们可以使用ES6 find() find()位于Array上。原型,所以它可以用于每个数组。 Find()接受一个测试布尔条件的回调。函数返回值(不是索引!)

例子:

Const array = [4,33,8,56,23]; Const found = array。Find (element => { 返回元素> 50; }); console.log(发现);/ / 56

Javascript中没有内置函数来执行此搜索。

如果你正在使用jQuery,你可以做一个jQuery. inarray(元素,数组)。

一种不太优雅的方法是抛出所有正确的错误消息(基于Array.prototype.filter),但将停止对第一个结果的迭代

function findFirst(arr, test, context) {
    var Result = function (v, i) {this.value = v; this.index = i;};
    try {
        Array.prototype.filter.call(arr, function (v, i, a) {
            if (test(v, i, a)) throw new Result(v, i);
        }, context);
    } catch (e) {
        if (e instanceof Result) return e;
        throw e;
    }
}

接下来的例子是

findFirst([-2, -1, 0, 1, 2, 3], function (e) {return e > 1 && e % 2;});
// Result {value: 3, index: 5}
findFirst([0, 1, 2, 3], 0);               // bad function param
// TypeError: number is not a function
findFirst(0, function () {return true;}); // bad arr param
// undefined
findFirst([1], function (e) {return 0;}); // no match
// undefined

它通过使用throw结束过滤器来工作。

我从互联网上的多个来源获得灵感,推导出下面的解决方案。希望考虑到一些默认值,并提供一种方法来比较每个条目的通用方法,这就解决了。

用法:(给出值“秒”)

var defaultItemValue = { id: -1, name: "Undefined" };
var containers: Container[] = [{ id: 1, name: "First" }, { id: 2, name: "Second" }];
GetContainer(2).name;

实现:

class Container {
    id: number;
    name: string;
}

public GetContainer(containerId: number): Container {
  var comparator = (item: Container): boolean => {
      return item.id == containerId;
    };
    return this.Get<Container>(this.containers, comparator, this.defaultItemValue);
  }

private Get<T>(array: T[], comparator: (item: T) => boolean, defaultValue: T): T {
  var found: T = null;
  array.some(function(element, index) {
    if (comparator(element)) {
      found = element;
      return true;
    }
  });

  if (!found) {
    found = defaultValue;
  }

  return found;
}

从ECMAScript 6开始,你可以使用Array.prototype.find。这可以在Firefox(25.0)、Chrome(45.0)、Edge(12)和Safari(7.1)中实现,但不能在Internet Explorer或其他一堆旧的或不常见的平台上实现。

例如,下面的x为106:

Const x =[100,101,102,103,104,105,106,107,108,109]。Find (function (el) { 返回el > 105; }); console.log (x);

If you want to use this right now but need support for IE or other unsupporting browsers, you can use a shim. I recommend the es6-shim. MDN also offers a shim if for some reason you don't want to put the whole es6-shim into your project. For maximum compatibility you want the es6-shim, because unlike the MDN version it detects buggy native implementations of find and overwrites them (see the comment that begins "Work around bugs in Array#find and Array#findIndex" and the lines immediately following it).