These are chat archives for ramda/ramda

21st
Dec 2017
Rolf Strijdhorst
@rolfst
Dec 21 2017 14:47

Can someone help in pointing a direction to remove multiple properties in a nested object? Eg.

{ name: 'kitchen',
  drawers: {
    pans: 1,
    plates: 28,
    glasses: 50,
    towels: 10,
    garbage: 40
  }
}

I want to remove the glasses, towels, and garbage.
would I create a lens for drawers and then do an omit? which sounds weird in my ears
Or should I call dissocPath a couple of times?

Michael Rosata
@mrosata
Dec 21 2017 14:49
@rolfst I would map over the prop names with dissocPath
actually, omit is better, sorry
Rolf Strijdhorst
@rolfst
Dec 21 2017 14:56
@mrosata tnx
Michael Rosata
@mrosata
Dec 21 2017 14:56
np
@rolfst you could make a util for it, const omitPropsFromNs = propKeys => ns => over(lensProp(ns), omit(propKeys)) then switch around the argument order to suit your senario
that might abstract the awkwardness of the lens
Rolf Strijdhorst
@rolfst
Dec 21 2017 14:58
it definitely makes it easier to read for my coworkers
Michael Rosata
@mrosata
Dec 21 2017 14:58
:)
Francisco
@franciscotln
Dec 21 2017 17:18
@rolfst have a look at evolve combined with omit. I think it's quite clean.
https://goo.gl/wUACB7
functionalStoic
@functionalStoic
Dec 21 2017 18:00
Is there a way to use the placeholder function to fill 3 spots that needs the same value without giving it 3 values?
Brad Compton (he/him)
@Bradcomp
Dec 21 2017 18:01
You could use converge, or probably some combo with apply
functionalStoic
@functionalStoic
Dec 21 2017 18:01
Ok Thanks I’ll look at both of those
Brad Compton (he/him)
@Bradcomp
Dec 21 2017 18:01
converge(trinary, [id, id, id])(val);
where id is the identity function
functionalStoic
@functionalStoic
Dec 21 2017 18:03
(
  wallFrames: Array<{ id: string }>,
  fdwdFrames: Array<fdwdFrame>
) =>
  map(({ id }) => {
    const fdwdFrame = find(propEq('id', id))(fdwdFrames);
    return isCanvasPrint(fdwdFrame)
      ? canvasPrintPath(fdwdFrame)
      : framePath(fdwdFrame);
  })(wallFrames);
This is what I’m working on.
Brad Compton (he/him)
@Bradcomp
Dec 21 2017 18:03
R.ifElse
Brad Compton (he/him)
@Bradcomp
Dec 21 2017 18:04
ifElse(isCanvasPrint, canvasPrintPath, framePath)(fdwdFrames);
Gimme a minute
functionalStoic
@functionalStoic
Dec 21 2017 18:07
Well maybe me a minute as well to soak it in. Ha!
Michael Rosata
@mrosata
Dec 21 2017 18:09
@JasonSooter can you do something like:
const fn = (
  fdwdFrames ,
) => 
  map((
     { id},
     fdwdFramesThing = find(propEq('id', id))(fdwdFrames)
  ) => 
    ifElse(isCanvasPrint, canvasPrintPath, framePath)(fdwdFramesThing)
I didn't try running it, but basically setup the thing you want to use 3 times inside the parameters to the function
I'm not sure if it would work, but since map doesn't pass a 2nd parameter it might
Brad Compton (he/him)
@Bradcomp
Dec 21 2017 18:14
const f = (fdwdFrames) => pipe(
  prop('id'), 
  find(propEq('id', R.__, fdwdFrames)), 
  ifElse(isCanvasPrint, canvasPrintPath, framePath)
);

map(f(fdwdFrames), wallFrames)
Do you have some test data and mock implementations we could test that with?
Matthew Willhite
@miwillhite
Dec 21 2017 18:16
I think the find needs to be something like this…
compose(find(__, fdwdFrames), propEq(‘id’))
Brad Compton (he/him)
@Bradcomp
Dec 21 2017 18:17
Oh good point
functionalStoic
@functionalStoic
Dec 21 2017 18:17
Yeah let me try that out
Thanks for the help
Brad Compton (he/him)
@Bradcomp
Dec 21 2017 18:18
const f = (fdwdFrames) => pipe(
  prop('id'), 
  o(flip(find)(fdwdFrames), propEq('id')), 
  ifElse(isCanvasPrint, canvasPrintPath, framePath)
);
:point_up: @miwillhite is right that my initial find won't work
Matthew Willhite
@miwillhite
Dec 21 2017 18:20
what is the signature of framePath? that would accept undefined?
functionalStoic
@functionalStoic
Dec 21 2017 18:22
@miwillhite It has the same signature as canvasPrintPath. It’s pulling different info out of the fdwdFrame object but returning a string very similar
Matthew Willhite
@miwillhite
Dec 21 2017 18:23
but if find doesn’t find anything it will return undefined correct?
which would get passed to framePath
Matthew Willhite
@miwillhite
Dec 21 2017 18:29
ok, so fdwdFrames is not homogeneous it would contain two or more types CanvasPrint and CanvasPrintPath correct?
assuming those were “types"
functionalStoic
@functionalStoic
Dec 21 2017 18:29
const isCanvasPrint = ({ openingImg, frameType }) =>
  startCase(frameType) == 'Canvas' && openingImg == 'print';
Matthew Willhite
@miwillhite
Dec 21 2017 18:29
you are assuming something will be found, at which point you determine what it is and act accordingly
functionalStoic
@functionalStoic
Dec 21 2017 18:30
Exactly
const canvasPrintPath = ({ IDH, IDW, canvasWrap, id }) =>
  `Single-Canvas-${IDH}X${IDW}-${canvasWrap}-printID|${id}`;
Matthew Willhite
@miwillhite
Dec 21 2017 18:30
got it, thanks :)
functionalStoic
@functionalStoic
Dec 21 2017 18:38
@Bradcomp @miwillhite Thanks for the help. That solution worked. I was just using this as an example to figure out a good way to solve it with Ramda. Does ifElse pass the return value of the previous function inside a pipe to each of its arguments or how did that work?
Matthew Willhite
@miwillhite
Dec 21 2017 18:39
yes, each function in ifElse will receive the result of the previous function in the pipe
functionalStoic
@functionalStoic
Dec 21 2017 18:39
ok thanks!
Brad Compton (he/him)
@Bradcomp
Dec 21 2017 18:39
Correct. It's lazy though. It will first evaluate the predicate, then only one of the forks
Matthew Willhite
@miwillhite
Dec 21 2017 18:39
:point_up:
@JasonSooter if you aren’t working with Daggy it can be a great way to discern types and organize data
Brad Compton (he/him)
@Bradcomp
Dec 21 2017 18:41
:+1: daggy
functionalStoic
@functionalStoic
Dec 21 2017 18:42
Haven’t come across it. I’ll dig into it
Is there some way it should be used here?
Matthew Willhite
@miwillhite
Dec 21 2017 18:43
well…for example…if you had multiple types of paths:
const Path = taggedSum(‘Path’, {
  CanvasPath: [‘a’, ‘b’, ‘c’],
  OtherPath: [‘a’, ‘b’],
});
Francisco
@franciscotln
Dec 21 2017 18:44
If I may add (cuz I'm not sure of your data structure), R.find returns a "Maybe", I'd add a defaultTo({}) after the find() in the pipe, just in case.
Matthew Willhite
@miwillhite
Dec 21 2017 18:44
then you could get rid of the ifElse and make a function that operates on all Path types
and start thinking about that undefined that you may get with find instead ;)
your function operating on the result of the find would then look like this:
Maybe Path -> String
or if you don’t have Maybe: Path | Undefined -> String
maybe it is something like this:
const buildPath = path =>
  path.cata({
    CanvasPath: (a, b, c) => …build the string,
    OtherPath: (a, b) => … build the string,
  });

Using Sanctuary + Ramda you could end up with something like this:

pipe([
  get(is(Integer), 'id'),        // Maybe Integer
  map(propEq('id')),             // Maybe (Any -> Bool)
  chain(flip(find)(fdwdFrames)), // Maybe Path
  maybe_('', buildPath),         // Path
])

(Just a rough idea…)

functionalStoic
@functionalStoic
Dec 21 2017 18:49
Hmm. ok. Daggy looks great
Matthew Willhite
@miwillhite
Dec 21 2017 18:49
But that all depends on how you’ve structured fdwdFrames
obviously it becomes a bit easier if it is homogeneous: [Path]
functionalStoic
@functionalStoic
Dec 21 2017 18:49
It’s an array with objects
Matthew Willhite
@miwillhite
Dec 21 2017 18:49
which I suspect is not the case here
Are the objects of the same type? or are they distinct?
functionalStoic
@functionalStoic
Dec 21 2017 18:51
Very close to the same type
Matthew Willhite
@miwillhite
Dec 21 2017 18:51
~which I suspect is not the case here~ I take that back
I was misreading above
yeah…so you could call those both Path, then you are just operating on a single type
functionalStoic
@functionalStoic
Dec 21 2017 18:52
{
  "projectid": "686522",
  "style": "Audrey",
  "color": "Black",
  "ODW": 20,
  "ODH": 17,
  "IDW": 14,
  "IDH": 11,
  "img": "https://www.theorganicbloom.com/designerapp/images/empty.png",
  "imgratio": 0,
  "imgxratio": 0,
  "imgyratio": 0,
  "imgrotate": 0,
  "rotate": 0,
  "title": "Audrey 11x14 Black",
  "openingImg": "empty",
  "frameType": "single",
  "type": "single",
  "secondColor": "",
  "innerFrameSizeW": 0,
  "innerFrameSizeH": 0,
  "print": 0,
  "printFromCart": 0,
  "id": "44729",
  "render": "https://s3.amazonaws.com/obdesigner/userframes/686522/5a344f0170338748688136-thumb.png",
  "wallpos": []
}
Matthew Willhite
@miwillhite
Dec 21 2017 18:52
that let’s your pipe logic handle the case where find may not render results
and it lets the function that operates on the found object worry about distinguishing types…er subtypes? I don’t have the vocabulary
data constructors…I believe
Path I think is the data type
CanvasPath and FramePath are the data constructors
functionalStoic
@functionalStoic
Dec 21 2017 18:54
Ok
Matthew Willhite
@miwillhite
Dec 21 2017 18:54
anyways…daggy is great for formalizing these kinds of structures
functionalStoic
@functionalStoic
Dec 21 2017 18:55
I really appreciate all the help and info. Exactly what I needed to go dig into some stuff ;-)
Matthew Willhite
@miwillhite
Dec 21 2017 18:55
then you can define .map on your data type and make the implementation specific to each constructor
Path.prototype.map = 
Path.prototype[‘fantasy-land/map’] =  
function Path$map (f) {
  this.cata({
    CanvasPath: (a, b, c) => …,
    FramePath: (a, b) => …,
  });
};
map(doCoolThingsWithMyPath, path);
and it all works like magic :sparkles: :sweat_smile:
functionalStoic
@functionalStoic
Dec 21 2017 18:58
Ha!
magic indeed at the moment