developer tip

JavaScript에서 Array.map으로 요소 제거

copycodes 2020. 10. 29. 08:17
반응형

JavaScript에서 Array.map으로 요소 제거


map()함수 를 사용하여 항목 배열을 필터링하고 싶습니다 . 다음은 코드 조각입니다.

var filteredItems = items.map(function(item)
{
    if( ...some condition... )
    {
        return item;
    }
});

문제는 필터링 된 항목이 여전히 배열의 공간을 사용하므로 완전히 지우고 싶습니다.

어떤 생각?

편집 : 덕분에, 나는 약 잊고 filter(), 내가 원하는 것은 사실이다 filter()다음 map().

EDIT2 : 그 지적에 대한 감사 map()filter()내 특정 코드가 브라우저에서 실행하도록 구성되지 않았지만, 모든 브라우저에서 구현되지 않습니다.


filter필터링 외에도 배열의 항목을 변경하려는 경우가 아니라면 매핑보다는 메서드를 사용해야합니다 .

예.

var filteredItems = items.filter(function(item)
{
    return ...some condition...;
});

[편집 : 물론 당신은 항상 sourceArray.filter(...).map(...)필터링과 돌연변이 모두 할 수 있습니다 ]


얼마 전에 답을 썼는데 의견이 바뀌 었습니다. 이 주제를 확장하고 훨씬 더 잘 설명하는 블로그 게시물확인하는 것이 좋습니다 . 또한 대안의 끝에서 JSperf 비교를 제공합니다.

tl; dr은 다음과 같습니다. 원하는 것을 수행하려면 (한 함수 호출 내에서 필터링 및 매핑)Array.reduce() . 그러나, 더 읽기 보통 빨리 접근 방식은 사용 필터이며 서로 연결하는지도 :

[1,2,3].filter(num => num > 2).map(num => num * 2)

다음은 Array.reduce()작동 방식과이를 사용하여 한 번의 반복으로 필터 및 매핑을 수행하는 방법에 대한 설명입니다 . 이것이 너무 요약 된 경우, 위에 링크 된 블로그 게시물을 보는 것이 좋습니다. 이는 명확한 예제와 진행 과정이 포함 된 훨씬 더 친숙한 소개입니다.

(일반적으로 익명) 함수 인 인수를 줄입니다.

이 익명 함수 는 두 개의 매개 변수를 사용합니다. 하나 (map / filter / forEach에 전달 된 익명 함수)는 작동 할 반복자입니다. 그러나이를 줄이기 위해 전달 된 익명 함수에 대한 또 다른 인수가 있는데, 이러한 함수는 허용하지 않으며 , 이는 종종 memo 라고하는 함수 호출 사이에 전달 될 값입니다 .

Array.filter ()는 하나의 인수 (함수) 만 사용하는 반면 Array.reduce ()는 중요한 (선택 사항이지만) 두 번째 인수도 사용합니다. 첫 번째 인수이며 이후에 함수 호출 사이에 변경되어 전달 될 수 있습니다. (제공되지 않은 경우 첫 번째 익명 함수 호출의 'memo'는 기본적으로 첫 번째 iteratee가되고 'iteratee'인수는 실제로 배열의 두 번째 값이됩니다.)

우리의 경우, 시작하기 위해 빈 배열을 전달한 다음, 함수를 기반으로 배열에 iteratee를 삽입할지 여부를 선택합니다. 이것이 필터링 프로세스입니다.

마지막으로 각 익명 함수 호출에서 '진행중인 배열'을 반환하고, reduce는 해당 반환 값을 가져 와서 다음 함수 호출에 인수 (메모라고 함)로 전달합니다.

이를 통해 필터와 맵이 한 번의 반복으로 발생하여 필요한 반복 횟수를 절반으로 줄일 수 있습니다. :)

자세한 설명은 MDN 또는 위의 링크를 참조하십시오 . :)

Reduce 호출의 기본 예 :

let array = [1,2,3];
const initialMemo = [];

array = array.reduce((memo, iteratee) => {
    // if condition is our filter
    if (iteratee > 1) {
        // what happens inside the filter is the map
        memo.push(iteratee * 2); 
    }

    // this return value will be passed in as the 'memo' argument
    // to the next call of this function, and this function will have
    // every element passed into it at some point.
    return memo; 
}, initialMemo)

console.log(array) // [4,6], equivalent to [(2 * 2), (3 * 2)]

더 간결한 버전 :

[1,2,3].reduce((memo, value) => value > 1 ? memo.concat(value * 2) : memo, [])

첫 번째 iteratee는 1보다 크지 않으므로 필터링되었습니다. 또한 그 존재를 명확하게하고 관심을 끌기 위해 이름이 지정된 initialMemo에 주목하십시오. 다시 한 번, 첫 번째 익명 함수 호출에 'memo'로 전달되고 익명 함수의 반환 된 값은 다음 함수에 'memo'인수로 전달됩니다.

메모에 대한 고전적인 사용 사례의 또 다른 예는 배열에서 가장 작거나 가장 큰 숫자를 반환하는 것입니다. 예:

[7,4,1,99,57,2,1,100].reduce((memo, val) => memo > val ? memo : val)
// ^this would return the largest number in the list.

자신의 감소 함수를 작성하는 방법의 예 (이는 종종 다음과 같은 함수를 이해하는 데 도움이됩니다.)

test_arr = [];

// we accept an anonymous function, and an optional 'initial memo' value.
test_arr.my_reducer = function(reduceFunc, initialMemo) {
    // if we did not pass in a second argument, then our first memo value 
    // will be whatever is in index zero. (Otherwise, it will 
    // be that second argument.)
    const initialMemoIsIndexZero = arguments.length < 2;

    // here we use that logic to set the memo value accordingly.
    let memo = initialMemoIsIndexZero ? this[0] : initialMemo;

    // here we use that same boolean to decide whether the first
    // value we pass in as iteratee is either the first or second
    // element
    const initialIteratee = initialMemoIsIndexZero ? 1 : 0;

    for (var i = initialIteratee; i < this.length; i++) {
        // memo is either the argument passed in above, or the 
        // first item in the list. initialIteratee is either the
        // first item in the list, or the second item in the list.
        memo = reduceFunc(memo, this[i]);
    }

    // after we've compressed the array into a single value,
    // we return it.
    return memo;
}

예를 들어 실제 구현에서는 인덱스와 같은 항목에 액세스 할 수 있지만 이것이 요점에 대한 복잡하지 않은 느낌을 얻는 데 도움이되기를 바랍니다.


그것은지도가하는 일이 아닙니다. 정말 Array.filter 원합니다 . 또는 원래 목록에서 요소를 정말로 제거하려면 for 루프를 사용하여 명령 적으로 수행해야합니다.


배열 필터 방법

var arr = [1, 2, 3]

// ES5 syntax
arr = arr.filter(function(item){ return item != 3 })

// ES2015 syntax
arr = arr.filter(item => item != 3)

console.log( arr )


그러나은 Array.filter모든 브라우저에서 지원되지 않으므로 프로토 타입을 작성해야합니다.

//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.filter)
{
    Array.prototype.filter = function(fun /*, thisp*/)
    {
        var len = this.length;

        if (typeof fun != "function")
            throw new TypeError();

        var res = new Array();
        var thisp = arguments[1];

        for (var i = 0; i < len; i++)
        {
            if (i in this)
            {
                var val = this[i]; // in case fun mutates this

                if (fun.call(thisp, val, i, this))
                   res.push(val);
            }
        }

        return res;
    };
}

그렇게하면 필요한 모든 메서드를 프로토 타입 할 수 있습니다.


following statement cleans object using map function.

var arraytoclean = [{v:65, toberemoved:"gronf"}, {v:12, toberemoved:null}, {v:4}];
arraytoclean.map((x,i)=>x.toberemoved=undefined);
console.dir(arraytoclean);

참고URL : https://stackoverflow.com/questions/9289/removing-elements-with-array-map-in-javascript

반응형