Метод массива фильтр, возвращает целый объект, а надо только несколько полей из объекта если фильтр тру

Есть код, он работает правильно, но проблема в том что если filter тру, то он возвращает целый объект, а надо только пару полей из объекта.

Я сделл кастомный фильтр через forEach, хочу узнать, есть ли элегантное решеие этого вопроса?

Мой кастомный фильтр и метод filter который возвращает целый объект, ниже.

[{
  name: {
    title: 'Mr',
    first: 'Test1',
    last: 'Linna1'
  },
  name: {
    title: 'Mr',
    first: 'Test2',
    last: 'Linna2'
  },
  name: {
    title: 'Mr',
    first: 'Test3',
    last: 'Linna3'
  }
}]

Кастомный

const getLabelUser = (data, state) => {
  let labelUser = null;
  state.users.forEach(user => {
    if (user.name.title === data) {
      labelUser = {
        name: user.name.title,
      };
    }
  });
  if (labelUser) {
    return labelUser;
  }
};

Первый вариант

const getLabelUser = (data, state) =>
  state.users.filter(
    user =>
      user.name.title === data && {
        name: user.name.title,
      }
  );

Ответы (3 шт):

Автор решения: DiD

Я не знаю какую элегантность вы ищите. Во первых, filter возвращает не объект, а массив объектов. К тому же, если вы ожидаете, что будет единственный результат, то лучше использовать методы find или findIndex.

Дальше если вы хотите получить некоторые поля из объекта, можно это сделать так:

const { title: name } = { title: 'Mr', first: 'Test3', last: 'Linna3' };
// name = 'Mr'

Или если в массиве:

const [ { title: name } ] =  [ { title: 'Mr', first: 'Test3', last: 'Linna3' }];
// name = 'Mr'

И вообще, в вашем коде, по моему мнению, лучше использовать цикл for-of вместо forEach. В вашем случае это будет нагляднее. Но о вкусах не спорят.

→ Ссылка
Автор решения: твой кот

Можно через map:

const [getLabelUser] = (data, state) => state.users.map(user => user.name.title === data && { name: user.name.title, }).filter(Boolean); 
→ Ссылка
Автор решения: Yugofx

Вы не фильтруете, а ищете первое попавшееся под ваше условие. Поэтому наиболее уместно использовать метод Array.prototype.find. Если найден подходящий объект, итерация массива мгновенно прекращается.

Тогда ваш кастомный метод может выглядеть вот так:

function getLabelUser(data, state) {
    const user = state.users.find(user => user.name.title === data);
    return user && data; // Да, можно вернуть прям data, раз вы ничего специфичного не ищете в этих объектах
}

Можно метод сделать чуть более общим:

// Ищет нужный объект по параметру сравнения в указанном пути и, если найдено, возвращает его
function findAndPluck(arrayOfObjects, lookupData, path) {
    // метод безопасно ищет свойство в глубине объекта
    const pluck = (object, path) => {
        let obj = object;
        const propPath = path.split('.').filter(Boolean);
        for (const prop of propPath) {
            obj = obj[prop];
            if (!obj) return;
        }
        return obj;
    };
    const found = arrayOfObjects.find(obj => lookupData === pluck(obj, path));
    return found && lookupData;
}
// ...
findAndPluck(state.users, 'Семен', 'name.title');
→ Ссылка