Programing

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

lottogame 2020. 5. 22. 08:06
반응형

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을 추천합니다 . MDN도 제공 어떤 이유로 당신이 당신의 프로젝트에 전체 ES6-심을 넣어하지 않으려는 경우입니다. 호환성을 최대화하려면 es6-shim을 원합니다. MDN 버전과 달리 버그가있는 기본 구현을 감지 find하고 덮어 씁니다 ( "Array # find 및 Array # findIndex의 버그 해결"으로 시작하는 주석 및 바로 다음 줄 참조). .


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

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

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

  1. Array.prototype.some(fn) offers the desired behaviour of stopping when a condition is met, but returns only whether an element is present; it's not hard to apply some trickery, such as the solution offered by Bergi's answer.

  2. Array.prototype.filter(fn)[0] makes for a great one-liner but is the least efficient, because you throw away N - 1 elements just to get what you need.

Traditional search methods in JavaScript are characterized by returning the index of the found element instead of the element itself or -1. This avoids having to choose a return value from the domain of all possible types; an index can only be a number and negative values are invalid.

Both solutions above don't support offset searching either, so I've decided to write this:

(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

If you're using underscore.js you can use its find and indexOf functions to get exactly what you want:

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

Documentation:


Summary:

  • For finding the first element in an array which matches a boolean condition we can use the ES6 find()
  • find() is located on Array.prototype so it can be used on every array.
  • find() takes a callback where a boolean condition is tested. The function returns the value (not the index!)

Example:

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

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

console.log(found);   //  56


As of ES 2015, Array.prototype.find() provides for this exact functionality.

For browsers that do not support this feature, the Mozilla Developer Network has provided a polyfill (pasted below):

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

Array.prototype.find() does just that, more info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find


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

I have got inspiration from multiple sources on the internet to derive into the solution below. Wanted to take into account both some default value and to provide a way to compare each entry for a generic approach which this solves.

Usage: (giving value "Second")

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

Implementation:

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

There is no built-in function in Javascript to perform this search.

If you are using jQuery you could do a jQuery.inArray(element,array).


A less elegant way that will throw all the right error messages (based on Array.prototype.filter) but will stop iterating on the first result is

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

Then examples are

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

It works by ending filter by using throw.

참고URL : https://stackoverflow.com/questions/10457264/how-to-find-first-element-of-array-matching-a-boolean-condition-in-javascript

반응형