0

I am trying to adopt Lodash functional programming functions and replacing _.chain with the flow. However, filter key passed into the flow is undefined:

import flow from 'lodash/fp/flow';
import filter from 'lodash/fp/filter';

flow(
  filter((value, key) => console.log(value, key)) // key is undefined
)({ name: "Tobi", year: 2017, });
Shota
  • 6,910
  • 9
  • 37
  • 67
  • So I wrote a long answer below describing some of the problems here, but what are you *really* trying to do? Given your input, what would you like your output to be? – Mulan Feb 16 '17 at 21:58
  • Thank you for the detailed answer. I will analyze your answer tomorrow. What I am trying to do is to move from _.chain to flow. Generally, I use _.chain to get some specific part of data from the response JSON or reformat it to be usable for some components or sort it or do all these things together. – Shota Feb 16 '17 at 22:16
  • you might be interested in a couple of my recent answers regarding Lodash's `flow`: [*Function composition with Lodash flow*](http://stackoverflow.com/a/42139851/633183) and [*Composing functions of varying arity using Lodash flow*](http://stackoverflow.com/a/42166494/633183) – let me know if I can help you in any other way ^_^ – Mulan Feb 16 '17 at 22:19
  • Wow, looks really great explanations. Thanks – Shota Feb 16 '17 at 22:23

1 Answers1

4

You have several problems about assumptions you've made here


1. Objects aren't considered a collection

Your code is basically doing this

// f = your filtering function
filter(f, {name: "Tobi", year: 2017})
// => ["Tobi", 2017]

That's because filter will implicitly convert the Object to an Array of the object's values if an Object is given

To convert an Object to an Array of key/value pairs, use Lodash's _.toPairs function

_.toPairs({name: "Tobi", year: 2017})
// => [ [ "name", "Tobi" ], [ "year", 2017 ] ]

2. Your filtering function parameters are backwards/wrong

Even if we were to utilize _.toPairs, your code would be doing this

_.filter((value, key) => ..., _.toPairs(data),)

Not only is the order backwards, but looking at the data, notice we'll be passing a single Array (a [key, value] pair) to the filtering function. That means we'll have to update the function to destructure the element like so

_.filter(([key, value]) => console.log(key, value), _.toPairs(data))
// name Tobi
// year 2017
// => []

Putting it all together

const app = _.flow (
  _.toPairs,
  _.filter(([key, value]) => console.log(key, value)))

app ({name: "Tobi", year: 2017})
// name Tobi
// year 2017
// => []

Why this is still weird and pointless

Well for starters, the filtering function just performs a console.log so there's really no point to anything we've done here.

I assume the point of the console.log was to just see if filter was even working, but you'll have to ask yourself what it even means to "filter an object".

  • What sort of output are you even expecting ?
  • Are we expecting an Object to be returned ?
  • Are we looking to return an Array of key/value pairs? Probably not, but then what? – maybe look at _.fromPairs that would convert the pairs back to an Object

Anyway, once you answer these questions, maybe you'll have a better idea of how to structure your program


Sensible Guess?

let isDigit = x => !Number.isNaN(Number(x))

// only keep object assignments where the value is a number
let app = _.flow(
  _.toPairs,
  _.filter(([key, value]) => isDigit(value)),
  _.fromPairs)

app ({name: "Tobi", year: 2017})
// => { year: 2017 }
Mulan
  • 129,518
  • 31
  • 228
  • 259
  • originally I didn't notice you were using `lodash/fp` – i've updated my answer accordingly – Mulan Feb 16 '17 at 22:12