Используя lodash, почему метод map в потоке не работает? - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть объект users, пытающийся использовать метод lodash map(), чтобы он возвращал только userIds, при этом отфильтровывая всех пользователей с currentUserId. Я хотел избежать использования chain(), так как он использует всю библиотеку, поэтому казалось, что метод flow() идеален, но он не сопоставляется с массивом идентификаторов.

import {
  map, filter, flow,
} from 'lodash';

const users = {
    123: {
      uid: 123
    },
    456: {
      uid: 456
    }
};

const currentUserId = 123;

const userIds = _.flow(
  _.map(user => user.uid),
  _.filter(userId => userId !== currentUserId),
)(users);

К сожалению, это возвращает тот же объект, который был передан в него. Как я могу получить массив с идентификаторами всех пользователей, которые не являются текущим пользователем?

Ответы [ 3 ]

0 голосов
/ 12 сентября 2018

Это можно сделать с помощью простого собственного JS-сокращения массива, созданного на Object#values() без кода, большего чем при использовании lodash

const users = {123: {uid: 123},456: {uid: 456}};

const currId = 123;


const userIds = Object.values(users)
            .reduce((a, {uid}) => uid !== currId ? a.concat(uid): a, [])
    

console.log(userIds)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>
0 голосов
/ 12 сентября 2018

Похоже, что вы не используете функциональную версию lodash .

var users = {
    123: {
      uid: 123
    },
    456: {
      uid: 456
    }
};
var currentUserId = 123;

const userIds = _.flow(
  _.map(user => user.uid),
  _.filter(userId => userId !== currentUserId)
)(users);

console.log("result with normal lodash", userIds);
<script src="https://cdn.jsdelivr.net/lodash/4/lodash.min.js"></script>

var users = {
    123: {
      uid: 123
    },
    456: {
      uid: 456
    }
};
var currentUserId = 123;

const userIds = _.flow(
  _.map(user => user.uid),
  _.filter(userId => userId !== currentUserId)
)(users);

console.log("result with lodash FP", userIds);
<script src="https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)"></script>

Согласно руководству по Lodash FP, вы должны импортировать его в свои файлы

// Load the fp build.
var fp = require('lodash/fp');

В вашем случае вы можете просто импортировать только map, filter и flow, но вы должны получить их варианты FP lodash.

0 голосов
/ 12 сентября 2018

Ответ распространяется на стандартную версию lodash.Пожалуйста, смотрите ответ @ Vlaz для ознакомления с функциональной версией lodash для программирования.


Когда вы пишете _.map(user => user.uid), это фактически вызывает функцию в то время.Что вы действительно пытаетесь сделать, так это создать функцию, которая похожа на _.map, но один из ее аргументов уже установлен.

К счастью, в Lodash есть встроенная функция для обработки этой ситуации - _.partialRight

const userIds = _.flow(
  _.partialRight(_.map, user => user.uid)
  _.partialRight(_.filter, userId => userId !== currentUserId),
)(users);

Документация


В качестве альтернативы, если вы хотите использовать простой JS вместо импорта новой функции, вы можете просто обернуть ее в анонимную функциюправильно передать аргументы.

const userIds = _.flow(
  (users) => _.map(users, user => user.uid),
  (users) => _.filter(users, userId => userId !== currentUserId),
)(users);
...