如何在JavaScript中找到与布尔条件匹配的数组的第一个元素?

如何在JavaScript中找到与布尔条件匹配的数组的第一个元素?,javascript,arrays,Javascript,Arrays,我想知道是否有一种已知的、内置的/优雅的方法可以找到与给定条件匹配的JS数组的第一个元素。一个C#等价物就是 到目前为止,我一直在使用两个函数组合,如下所示: // Returns the first element of an array that satisfies given predicate Array.prototype.findFirst = function (predicateCallback) { if (typeof predicateCallback !== 'f

我想知道是否有一种已知的、内置的/优雅的方法可以找到与给定条件匹配的JS数组的第一个元素。一个C#等价物就是

到目前为止,我一直在使用两个函数组合,如下所示:

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

但既然有,也许已经有这样的东西了?我想很多人必须一直实现这样的东西…

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

如果您使用的是jQuery,那么可以执行
jQuery.inArray(元素,数组)

如何使用并从结果数组中获取第一个索引

var result = someArray.filter(isNotNullNorUndefined)[0];

一种不太优雅的方法是
抛出所有正确的错误消息(基于
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
结束
filter
来工作,因为ES6是数组的本机;一旦找到第一个匹配项并返回值,就会停止枚举数组

const result = someArray.find(isNotNullNorUndefined);

旧答案:

我必须发布一个答案来阻止这些
过滤器
建议:-)

因为ECMAScript中有这么多函数式数组方法,也许已经有类似的东西了

您可以使用迭代数组,直到满足条件(然后停止)。不幸的是,它只返回条件是否满足一次,而不返回满足条件的元素(或索引)。因此,我们必须对其稍作修改:

function find(arr, test, ctx) {
    var result = null;
    arr.some(function(el, i) {
        return test.call(ctx, el, i, arr) ? ((result = el), true) : false;
    });
    return result;
}

如果您使用的是
underline.js
,您可以使用它的
find
indexOf
函数来获得您想要的:

var index = _.indexOf(your_array, _.find(your_array, function (d) {
    return d === true;
}));
文件:

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

现在应该很清楚,JavaScript本身并没有提供这样的解决方案;以下是最接近的两个导数,最有用的第一个:

  • Array.prototype.some(fn)
    在满足条件时提供所需的停止行为,但仅返回元素是否存在;运用一些诡计并不难,例如由提供的解决方案

  • Array.prototype.filter(fn)[0]
    是一个很好的单行程序,但效率最低,因为你扔掉
    N-1
    元素只是为了得到你需要的

  • JavaScript中的传统搜索方法的特点是返回找到的元素的索引,而不是返回元素本身或-1。这避免了必须从所有可能类型的域中选择返回值;索引只能是数字,负值无效

    上述两种解决方案也不支持偏移量搜索,因此我决定写以下内容:

    (function(ns) {
      ns.search = function(array, callback, offset) {
        var size = array.length;
    
        offset = offset || 0;
        if (offset >= size || offset <= -size) {
          return -1;
        } else if (offset < 0) {
          offset = size - offset;
        }
    
        while (offset < size) {
          if (callback(array[offset], offset, array)) {
            return offset;
          }
          ++offset;
        }
        return -1;
      };
    }(this));
    
    search([1, 2, NaN, 4], Number.isNaN); // 2
    search([1, 2, 3, 4], Number.isNaN); // -1
    search([1, NaN, 3, NaN], Number.isNaN, 2); // 3
    
    (函数(ns){
    ns.search=函数(数组、回调、偏移){
    var size=array.length;
    偏移量=偏移量| | 0;
    
    如果(offset>=size | | offset从ECMAScript 6开始,您可以使用它。这是在Firefox(25.0)、Chrome(45.0)、Edge(12)和Safari(7.1)中实现和工作的,但是

    例如,下面的
    x
    106

    const x=[100101102103104105106107108109]。查找(函数(el){
    返回el>105;
    });
    
    console.log(x);
    Array.prototype.find()正是这样做的,更多信息:

    从ES 2015开始,
    Array.prototype.find()
    提供了这一确切的功能

    对于不支持此功能的浏览器,Mozilla开发者网络提供了(粘贴在下面):

    if(!Array.prototype.find){
    Array.prototype.find=函数(谓词){
    if(this==null){
    抛出新的TypeError('Array.prototype.find调用为null或未定义');
    }
    if(类型谓词!=='function'){
    抛出新类型错误('谓词必须是函数');
    }
    变量列表=对象(此);
    var length=list.length>>>0;
    var thisArg=参数[1];
    var值;
    对于(变量i=0;i
    摘要:
    • 要查找与布尔条件匹配的数组中的第一个元素,我们可以使用
      ES6
      find()
    • find()
      位于
      阵列上。prototype
      可用于每个阵列
    • find()
    例子:
    const数组=[4,33,8,56,23];
    const found=array.find(元素=>{
    返回元素>50;
    });
    
    console.log(find);//56
    我从互联网上的多个来源获得灵感,从而衍生出下面的解决方案。我想考虑一些默认值,并提供一种方法来比较每个条目,以获得一种通用的解决方法

    用法:(赋予值“秒”)

    实施:

    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;
    }
    
    类容器{
    id:编号;
    名称:字符串;
    }
    publicGetContainer(containerId:number):容器{
    变量比较器=(项:容器):布尔=>{
    return item.id==集装箱id;
    };
    返回this.Get(this.containers、comparator、this.defaultItemValue);
    }
    私有Get(数组:T[],比较器:(项:T)=>布尔值,默认值:T):T{
    发现的变量:T=null;
    数组.some(函数(元素、索引){
    if(比较器(元件)){
    发现=元素;
    返回true;
    }
    });
    如果(!找到){
    发现=默认值;
    }
    发现退货;
    }
    
    使用前面编写的
    findIndex
    。下面是完整的示例:

    function find(arr, predicate) {
        foundIndex = arr.findIndex(predicate);
        return foundIndex !== -1 ? arr[foundIndex] : null;
    }
    
    用法如下(我们希望找到数组中第一个属性为
    id==1的元素)


    这里没有内置的方法,但是有一些实用程序库可以实现这个功能,比如下划线。js看起来确实很不错!它有find()。谢谢!正如你所知,你可以使用红色
    foundElement = myArray[myArray.findIndex(element => //condition here)];
    
    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;
    }
    
    function find(arr, predicate) {
        foundIndex = arr.findIndex(predicate);
        return foundIndex !== -1 ? arr[foundIndex] : null;
    }
    
    var firstElement = find(arr, e => e.id === 1);