[javascript] JavaScript에서 부울 조건과 일치하는 배열의 첫 번째 요소를 찾는 방법은 무엇입니까?

주어진 조건과 일치하는 JS 배열의 첫 번째 요소를 찾는 알려진 내장 / 우아한 방법이 있는지 궁금합니다. AC #에 상응하는 것은 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 에는 너무 많은 기능 스타일 배열 메소드가 있기 때문에 이미 이와 같은 것이 있습니까? 많은 사람들이 항상 이와 같은 것을 구현해야한다고 생각합니다 …



답변

ES6부터는 배열에 대한 기본 find방법 이 있습니다. 첫 번째 일치 항목을 찾으면 배열 열거를 중지하고 값을 반환합니다.

const result = someArray.find(isNotNullNorUndefined);

이전 답변 :

filter제안 을 중지하려면 답변을 게시해야 합니다 🙂

ECMAScript에는 많은 기능 스타일 배열 메소드가 있기 때문에 이미 이와 같은 것이 있습니까?

당신이 사용할 수있는 some배열 방법을 조건이 (정지 후 등) 충족 될 때까지 반복 배열을. 불행히도 조건이 충족 된 요소 (또는 색인)가 아닌 조건이 한 번만 충족되었는지 여부를 반환합니다. 따라서 약간 수정해야합니다.

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

var result = find(someArray, isNotNullNorUndefined);


답변

ECMAScript 6부터는이를 사용할 수 있습니다 Array.prototype.find. 이것은 Firefox (25.0), Chrome (45.0), Edge (12) 및 Safari (7.1)에서 구현되고 작동하지만 Internet Explorer 또는 기타 오래되거나 일반적이지 않은 플랫폼에서는 작동하지 않습니다 .

예를 들어 아래 식은로 평가됩니다 106.

[100,101,102,103,104,105,106,107,108,109].find(function (el) {
    return el > 105;
});

지금 이것을 사용하고 싶지만 IE 또는 다른 지원되지 않는 브라우저에 대한 지원이 필요한 경우 shim을 사용할 수 있습니다. es6-shim을 추천합니다 . 어떤 이유로 든 es6-shim 전체를 프로젝트에 포함하지 않으려는 경우 MDN은 shim 도 제공 합니다 . 호환성을 최대화하려면 es6-shim을 원합니다. MDN 버전과 달리 버그가있는 기본 구현을 감지 find하고 덮어 씁니다 ( “Array # find 및 Array # findIndex의 버그 해결”으로 시작하는 주석 및 바로 다음 줄 참조). .


답변

필터 를 사용 하고 결과 배열에서 첫 번째 색인을 얻는 방법은 무엇입니까 ?

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


답변

JavaScript는 기본적으로 그러한 솔루션을 제공하지 않습니다. 가장 근접한 두 가지 파생어는 다음과 같습니다.

  1. Array.prototype.some(fn)조건이 충족 될 때 원하는 중지 동작을 제공하지만 요소가 존재하는지 여부 만 반환합니다. Bergi의 답변에서 제공하는 솔루션과 같은 속임수를 적용하는 것은 어렵지 않습니다 .

  2. 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


답변

요약:

  • 부울 조건과 일치하는 배열에서 첫 번째 요소를 찾으려면 ES6 find()
  • find()에있는 Array.prototype그것의 모든 어레이에 이용 될 수 있도록.
  • find()boolean조건이 테스트 되는 콜백을받습니다 . 이 함수는 인덱스가 아닌 값을 반환합니다 .

예:

const array = [4, 33, 8, 56, 23];

const found = array.find((element) => {
  return element > 50;
});

console.log(found);   //  56


답변

당신이 사용하는 경우 underscore.js당신은 사용할 수 있습니다 findindexOf당신이 원하는 것을 정확하게 얻을 기능 :

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

선적 서류 비치:


답변

ES 2015 Array.prototype.find()에서이 정확한 기능을 제공합니다.

이 기능을 지원하지 않는 브라우저의 경우 Mozilla Developer Network는 다음과 같이 폴리 필 을 제공했습니다 .

if (!Array.prototype.find) {
  Array.prototype.find = function(predicate) {
    if (this === null) {
      throw new TypeError('Array.prototype.find called on null or undefined');
    }
    if (typeof predicate !== 'function') {
      throw new TypeError('predicate must be a function');
    }
    var list = Object(this);
    var length = list.length >>> 0;
    var thisArg = arguments[1];
    var value;

    for (var i = 0; i < length; i++) {
      value = list[i];
      if (predicate.call(thisArg, value, i, list)) {
        return value;
      }
    }
    return undefined;
  };
}