Подтвердить что ты не робот

Сопоставьте и отфильтруйте массив одновременно

У меня есть массив объектов, которые я хочу перебрать для создания нового фильтрованного массива. Но также, мне нужно отфильтровать некоторые из объектов из нового массива в зависимости от параметра. Я пробую это:

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

Это хороший подход? Есть ли лучший метод? Я открыт для использования любой библиотеки, такой как lodash.

4b9b3361

Ответ 1

Вы должны использовать 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>

Ответ 2

Используйте уменьшить, Люк!

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

Ответ 3

С ES6 вы можете сделать это очень коротко:

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

Ответ 4

Array.prototype.flatMap является еще одним вариантом.

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

Со страницы MDN, указанной выше:

flatMap можно использовать как способ добавления и удаления элементов (изменения количества элементов) во время карты. Другими словами, он позволяет сопоставить множество элементов множеству элементов (обрабатывая каждый элемент ввода отдельно), а не всегда один к одному. В этом смысле он работает как противоположность фильтра. Просто верните массив из 1 элемента, чтобы сохранить элемент, массив из нескольких элементов, чтобы добавить элементы, или массив из 0 элементов, чтобы удалить элемент.

Ответ 5

Одна линия reduce с ES6 фантазии распространение синтаксис здесь!

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

Ответ 6

Используйте Array.prototy.filter

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

Ответ 7

Используя сокращение, вы можете сделать это в одной функции Array.prototype. Это позволит получить все четные числа из массива.

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>

Ответ 8

В какой-то момент не проще (или просто так) использовать 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>

Ответ 9

Я оптимизировал ответы со следующими моментами:

Я представлю два решения, используя forEach, другой - reduce:

Решение 1: Использование 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);

Ответ 10

Я бы сделал комментарий, но у меня нет необходимой репутации. Небольшое улучшение для Максима Кузьмина, иначе очень хороший ответ, чтобы сделать его более эффективным:

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