These are chat archives for ramda/ramda

11th
Jan 2017
Sudarsan Balaji
@artfuldev
Jan 11 2017 15:53
that was very exciting, I really learnt a lot. I will continue learning. Thanks, everyone!
Matt Ross
@amsross
Jan 11 2017 17:04
I just asked this in sanctuary-js/sanctuary, but I’m cross-posting anyway, given that my concern is probably more ramda-centric than sanctuary-centric:
If I’ve got an object such that R.path([“not”, “in”, “object”], {}) returns undefined, how would I use that same sort of logic to instead of undefined, get back S.Nothing()?
Shane Keulen
@SeeThruHead
Jan 11 2017 20:51

am i crazy or would something like

export const mapObjWith = mappingObj => R.pipe(
  R.pick(R.keys(mappingObj)),
  R.merge(R.map(R.always(undefined), mappingObj)),
  R.evolve(mappingObj)
);

for mapping an object of functions over a matching object of values, without cloning, and without selectively applying transforms

Matt Ross
@amsross
Jan 11 2017 21:00
Why R.merge(R.map(R.always(undefined), mappingObj)),?
I would think maybe R.applySpec might be closer to what you want
since it looks like you only want the keys in mappingObj returned
Shane Keulen
@SeeThruHead
Jan 11 2017 21:05
yeah you could achieve the same function by using applySpec and composing each function with an R.prop of that functions key in the mapping object
Shane Keulen
@SeeThruHead
Jan 11 2017 21:13

thanks i didn't realize that implementation

export const mapObjWith = mappingObj => R.applySpec(
  R.mapObjIndexed((value, key) => R.compose(value, R.prop(key)))(mappingObj)
);

though this one does not handle nested objects function mappings like the evolve version

Matt Ross
@amsross
Jan 11 2017 21:15
I think it does
with path instead of prop, at least, no?
what does your mappingObj look like?
Shane Keulen
@SeeThruHead
Jan 11 2017 21:19
i'm using this a lot for form validations
{
  headline: headlineValid,
  stage: { questions: questionsValid },
  reporting_category: reportingValid
}
Matt Ross
@amsross
Jan 11 2017 21:20
so the values are functions?
Shane Keulen
@SeeThruHead
Jan 11 2017 21:21
yeah
Matt Ross
@amsross
Jan 11 2017 21:22
I use something like this where mappingObject is like { “a”: { “great”: { “prop”: R.path([“a”, “path”]) } } } , then is used like R.applySpec(mappingObj2)(inputObj)
just to get the value out, though
Shane Keulen
@SeeThruHead
Jan 11 2017 21:23
my issue is i need to return stage: { questions: false } }
as that's what my form library expects
and it would be nice to have mappingObj { stage: { questions: validationFunc } }
Matt Ross
@amsross
Jan 11 2017 21:23
This message was deleted
I would think that you qould still use R.applySpec, and then
const questionsValid = x => {
  return R.map(checkValidity, R.path([“stage”, “questions”], x));
}
or something like that
Shane Keulen
@SeeThruHead
Jan 11 2017 21:30
the key of the function must encapsulate the path at which to apply itself
Matt Ross
@amsross
Jan 11 2017 21:32
yeah
Shane Keulen
@SeeThruHead
Jan 11 2017 21:40
export const mapObjWith = mappingObj => R.applySpec(
  R.mapObjIndexed(
    (value, key) => {
      return R.compose(
        typeof mappingObj[key] === 'object' ? mapObjWith(mappingObj[key]) : value,
        R.prop(key)
      );
    }
  )(mappingObj)
);
like this
Denis Stoyanov
@xgrommx
Jan 11 2017 21:41
@SeeThruHead could u please provide source and destination what u want
Shane Keulen
@SeeThruHead
Jan 11 2017 21:42
console.log(mappingObj({
  a: R.toUpper,
  b: R.inc,
  c: R.dec,
  d: { e: R.inc }
})({
  a: 'bob',
  b: 3,
  c: 4,
  d: { e: 0 }
}));

{
  a: 'BOB',
  b: 4,
  c: 3,
  d: { e: 1 }
}
my code is working now, just wondering if this might be a good addition to the library, if other people have to do this as much as i do
Denis Stoyanov
@xgrommx
Jan 11 2017 21:43
@SeeThruHead why not just evolve?
Shane Keulen
@SeeThruHead
Jan 11 2017 21:44
it's similar but not exact to what i need
for instance i need tranforms to always be run, even if the key they operate on is undefined
and i do not want untranformed keys in the output, so a clone is not appropriate
another implementation would be
export const mapObjWith = mappingObj => R.pipe(
  R.pick(R.keys(mappingObj)),
  R.merge(R.map(R.always(undefined), mappingObj)),
  R.evolve(mappingObj)
);
Denis Stoyanov
@xgrommx
Jan 11 2017 21:45
@SeeThruHead please provide your case with undefined
Shane Keulen
@SeeThruHead
Jan 11 2017 21:48
```
console.log(mappingObj({
  a: R.toUpper,
  b: R.inc,
  c: R.dec,
  d: { e: R.inc }
})({
  a: 'bob',
  b: 3,
  c: 4,
  d: { e: undefined }
}));

{
  a: 'BOB',
  b: 4,
  c: 3,
  d: { e: NaN }
}
(the function would always be called with the corresponding property
Denis Stoyanov
@xgrommx
Jan 11 2017 21:50
@SeeThruHead evolve the same https://goo.gl/m4nCX1
Shane Keulen
@SeeThruHead
Jan 11 2017 21:51
are the main differences
Denis Stoyanov
@xgrommx
Jan 11 2017 22:00
@SeeThruHead sorry it isn't pointfree)
const f = p => o => {
  const pKeys = keys(p);
  const oKeys = keys(o);
  const commonKeys = intersection(pKeys, oKeys)

  return evolve(p)(pick(commonKeys, o))
}

f({
  a: R.toUpper,
  b: R.inc,
  c: R.dec,
  d: { e: R.inc }
})({
  a: 'bob',
  b: 3,
  c: 4,
  d: { e: undefined },
  z: 'i dont want this'
})
@SeeThruHead const f = p => o => evolve(p)(pick(useWith(intersection, [keys, keys])(p, o), o))
Shane Keulen
@SeeThruHead
Jan 11 2017 22:15
yeah that's close but still not quite there, keys that don't exist should be passed to their transformation functions as undefined no matter how deeply the key is nested
i think i have a method for that though