동시에 배열 매핑 및 필터링
새 필터링 된 배열을 생성하기 위해 반복하려는 개체 배열이 있습니다. 또한 매개 변수에 따라 새 배열에서 일부 객체를 필터링해야합니다. 나는 이것을 시도하고있다 :
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;
}, []);
}
ES6를 사용하면 매우 짧게 할 수 있습니다.
options.filter(opt => !opt.assigned).map(opt => someNewObject)
Array.prototype.flatMap 은 또 다른 옵션입니다.
options.flatMap(o => o.assigned ? [o.name] : []);
위에 링크 된 MDN 페이지에서 :
flatMap
can be used as a way to add and remove items (modify the number of items) during a map. In other words, it allows you to map many items to many items (by handling each input item separately), rather than always one-to-one. In this sense, it works like the opposite of filter. Simply return a 1-element array to keep the item, a multiple-element array to add items, or a 0-element array to remove the item.
One line reduce
with ES6 fancy spread syntax is here!
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);
Use Array.prototy.filter itself
function renderOptions(options) {
return options.filter(function(option){
return !option.assigned;
}).map(function (option) {
return (someNewObject);
});
}
I optimized the answers with the following points:
- Rewriting
if (cond) { stmt; }
ascond && stmt;
- Use ES6 Arrow Functions
I'll present two solutions, one using forEach, the other using reduce:
Solution 1: Using forEach
var options = [
{ name: 'One', assigned: true },
{ name: 'Two', assigned: false },
{ name: 'Three', assigned: true },
];
var reduced = []
options.forEach(o => {
o.assigned && reduced.push( { name: o.name, newProperty: 'Foo' } );
} );
console.log(reduced);
Solution 2: Using reduce
var options = [
{ name: 'One', assigned: true },
{ name: 'Two', assigned: false },
{ name: 'Three', assigned: true },
];
var reduced = options.reduce((a, o) => {
o.assigned && a.push( { name: o.name, newProperty: 'Foo' } );
return a;
}, [ ] );
console.log(reduced);
I leave it up to you to decide which solution to go for.
I'd make a comment, but I don't have the required reputation. A small improvement to Maxim Kuzmin's otherwise very good answer to make it more efficient:
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);
Explanation
Instead of spreading the entire result over and over for each iteration, we only append to the array, and only when there's actually a value to insert.
Using reduce, you can do this in one Array.prototype function. This will fetch all even numbers from an array.
var arr = [1,2,3,4,5,6,7,8];
var brr = arr.reduce(function(c,n){
if(n%2!=0){
return c;
}
c.push(n);
return c;
},[]);
document.getElementById('mypre').innerHTML = brr.toString();
<h1>Get all even numbers</h1>
<pre id="mypre"> </pre>
You can use the same method and generalize it for your objects, like this.
var arr = options.reduce(function(c,n){
if(somecondition){return c;}
c.push(n); return c;
},[]);
arr
will now contain the filtered objects.
At some point, isn't it easier(or just as easy) to use a forEach
var options = [
{ name: 'One', assigned: true },
{ name: 'Two', assigned: false },
{ name: 'Three', assigned: true },
];
var reduced = []
options.forEach(function(option) {
if (option.assigned) {
var someNewValue = { name: option.name, newProperty: 'Foo' }
reduced.push(someNewValue);
}
});
document.getElementById('output').innerHTML = JSON.stringify(reduced);
<h1>Only assigned options</h1>
<pre id="output"> </pre>
However it would be nice if there was a malter()
or fap()
function that combines the map
and filter
functions. It would work like a filter, except instead of returning true or false, it would return any object or a null/undefined.
참고URL : https://stackoverflow.com/questions/34398279/map-and-filter-an-array-at-the-same-time
'program tip' 카테고리의 다른 글
지점 기반 변경 (0) | 2020.08.09 |
---|---|
인터페이스와 클래스의 차이점은 무엇이며 클래스에서 직접 메서드를 구현할 수 있는데 인터페이스를 사용해야하는 이유는 무엇입니까? (0) | 2020.08.09 |
pip로 설치 한 후 "jupyter : 명령을 찾을 수 없음" (0) | 2020.08.09 |
개체를 null 대 Dispose ()로 설정 (0) | 2020.08.09 |
AngularJS로 이미지 가져 오기 요청 (0) | 2020.08.09 |