[javascript] 어레이를 동시에 매핑 및 필터링

새로운 필터링 된 배열을 생성하기 위해 반복하려는 객체 배열이 있습니다. 또한 매개 변수에 따라 새 배열에서 일부 객체를 필터링해야합니다. 나는 이것을 시도하고있다 :

function renderOptions(options) {
    return options.map(function (option) {
        if (!option.assigned) {
            return (someNewObject);
        }
    });
}

좋은 접근입니까? 더 좋은 방법이 있습니까? lodash와 같은 라이브러리를 사용할 수 있습니다.



답변

Array.reduce이것을 위해 사용해야 합니다.

var options = [
  { name: 'One', assigned: true },
  { name: 'Two', assigned: false },
  { name: 'Three', assigned: true },
];

var reduced = options.reduce(function(filtered, option) {
  if (option.assigned) {
     var someNewValue = { name: option.name, newProperty: 'Foo' }
     filtered.push(someNewValue);
  }
  return filtered;
}, []);

document.getElementById('output').innerHTML = JSON.stringify(reduced);
<h1>Only assigned options</h1>
<pre id="output"> </pre>


또는 감속기는 다음과 같은 순수한 기능 일 수 있습니다.

var reduced = options.reduce(function(result, option) {
  if (option.assigned) {
    return result.concat({
      name: option.name,
      newProperty: 'Foo'
    });
  }
  return result;
}, []);


답변

줄이지, 루크!

function renderOptions(options) {
    return options.reduce(function (res, option) {
        if (!option.assigned) {
            res.push(someNewObject);
        }
        return res;
    }, []);
}


답변

2019 년부터 Array.prototype.flatMap 이 좋은 옵션입니다.

options.flatMap(o => o.assigned ? [o.name] : []);

위에 링크 된 MDN 페이지에서 :

flatMap지도 중에 항목을 추가 및 제거 (항목 수 수정)하는 방법으로 사용할 수 있습니다. 즉, 항상 일대일이 아닌 여러 항목을 여러 항목에 매핑 할 수 있습니다 (각 입력 항목을 개별적으로 처리하여). 이런 의미에서 필터의 반대처럼 작동합니다. 항목을 유지하려면 1 요소 배열을, 항목을 추가하려면 여러 요소 배열을, 항목을 제거하려면 0 요소 배열을 리턴하십시오.


답변

ES6을 사용하면 매우 짧을 수 있습니다.

options.filter(opt => !opt.assigned).map(opt => someNewObject)


답변

reduceES6 멋진 확산 구문을 갖춘 한 줄 이 여기 있습니다!

var options = [
  { name: 'One', assigned: true },
  { name: 'Two', assigned: false },
  { name: 'Three', assigned: true },
];

const filtered = options
  .reduce((result, {name, assigned}) => [...result, ...assigned ? [name] : []], []);

console.log(filtered);


답변

의견을 말하지만 필요한 평판이 없습니다. Maxim Kuzmin의 효율성을 높이기 위해 아주 좋은 답변을 약간 개선했습니다.

const options = [
  { name: 'One', assigned: true },
  { name: 'Two', assigned: false },
  { name: 'Three', assigned: true },
];

const filtered = options
  .reduce((result, { name, assigned }) => assigned ? result.concat(name) : result, []);

console.log(filtered);

설명

반복 할 때마다 전체 결과를 반복해서 퍼 뜨리지 않고 실제로 삽입 할 값이있을 때만 배열에 추가합니다.


답변

Array.prototy.filter 자체 사용

function renderOptions(options) {
    return options.filter(function(option){
        return !option.assigned;
    }).map(function (option) {
        return (someNewObject);
    });
}