These are chat archives for ramda/ramda

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

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 UTC
@rolfst I would map over the prop names with dissocPath
actually, omit is better, sorry
Rolf Strijdhorst
@rolfst
Dec 21 2017 14:56 UTC
@mrosata tnx
Michael Rosata
@mrosata
Dec 21 2017 14:56 UTC
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 UTC
it definitely makes it easier to read for my coworkers
Michael Rosata
@mrosata
Dec 21 2017 14:58 UTC
:)
Francisco
@franciscotln
Dec 21 2017 17:18 UTC
@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 UTC
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 UTC
You could use converge, or probably some combo with apply
functionalStoic
@functionalStoic
Dec 21 2017 18:01 UTC
Ok Thanks I’ll look at both of those
Brad Compton (he/him)
@Bradcomp
Dec 21 2017 18:01 UTC
converge(trinary, [id, id, id])(val);
where id is the identity function
functionalStoic
@functionalStoic
Dec 21 2017 18:03 UTC
(
  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 UTC
R.ifElse
Brad Compton (he/him)
@Bradcomp
Dec 21 2017 18:04 UTC
ifElse(isCanvasPrint, canvasPrintPath, framePath)(fdwdFrames);
Gimme a minute
functionalStoic
@functionalStoic
Dec 21 2017 18:07 UTC
Well maybe me a minute as well to soak it in. Ha!
Michael Rosata
@mrosata
Dec 21 2017 18:09 UTC
@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 UTC
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 UTC
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 UTC
Oh good point
functionalStoic
@functionalStoic
Dec 21 2017 18:17 UTC
Yeah let me try that out
Thanks for the help
Brad Compton (he/him)
@Bradcomp
Dec 21 2017 18:18 UTC
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 UTC
what is the signature of framePath? that would accept undefined?
functionalStoic
@functionalStoic
Dec 21 2017 18:22 UTC
@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 UTC
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 UTC
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 UTC
const isCanvasPrint = ({ openingImg, frameType }) =>
  startCase(frameType) == 'Canvas' && openingImg == 'print';
Matthew Willhite
@miwillhite
Dec 21 2017 18:29 UTC
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 UTC
Exactly
const canvasPrintPath = ({ IDH, IDW, canvasWrap, id }) =>
  `Single-Canvas-${IDH}X${IDW}-${canvasWrap}-printID|${id}`;
Matthew Willhite
@miwillhite
Dec 21 2017 18:30 UTC
got it, thanks :)
functionalStoic
@functionalStoic
Dec 21 2017 18:38 UTC
@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 UTC
yes, each function in ifElse will receive the result of the previous function in the pipe
functionalStoic
@functionalStoic
Dec 21 2017 18:39 UTC
ok thanks!
Brad Compton (he/him)
@Bradcomp
Dec 21 2017 18:39 UTC
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 UTC
: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 UTC
:+1: daggy
functionalStoic
@functionalStoic
Dec 21 2017 18:42 UTC
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 UTC
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 UTC
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 UTC
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 UTC
Hmm. ok. Daggy looks great
Matthew Willhite
@miwillhite
Dec 21 2017 18:49 UTC
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 UTC
It’s an array with objects
Matthew Willhite
@miwillhite
Dec 21 2017 18:49 UTC
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 UTC
Very close to the same type
Matthew Willhite
@miwillhite
Dec 21 2017 18:51 UTC
~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 UTC
{
  "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 UTC
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 UTC
Ok
Matthew Willhite
@miwillhite
Dec 21 2017 18:54 UTC
anyways…daggy is great for formalizing these kinds of structures
functionalStoic
@functionalStoic
Dec 21 2017 18:55 UTC
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 UTC
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 UTC
Ha!
magic indeed at the moment