zenika-open-source / immutadot

immutadot is a JavaScript library to deal with nested immutable structures.
https://immutadot.zenika.com
MIT License
178 stars 5 forks source link

Improve "lazy" get ? #306

Closed nlepage closed 6 years ago

nlepage commented 6 years ago

The "lazy" get is unusable with slices:

const obj = { arr: [
  { nested1: { val: 'foo' }, nested2: { val: 'bar' } },
  { nested1: { val: 'aze' }, nested2: { val: 'rty' } },
] }
set(obj, 'arr[:].nested1.val', get('arr[:].nested2.val'))
// returns
// { arr: [
//   { nested1: { val: ['bar', 'rty'] }, nested2: { val: 'bar' } },
//   { nested1: { val: ['bar', 'rty'] }, nested2: { val: 'rty' } },
// ] }
// it would be nice to have
// { arr: [
//   { nested1: { val: 'bar' }, nested2: { val: 'bar' } },
//   { nested1: { val: 'rty' }, nested2: { val: 'rty' } },
// ] }
nlepage commented 6 years ago

IMO the current behavior is correct.

But it would be nice to have some mechanism to achieve a "lazy" get inside a slice.

ES version:

{
  ...obj,
  arr: obj.arr.map(({ nested1, nested2, ...rest }) => ({
    ...rest,
    nested1: {
      ...nested1,
      val: nested2.val,
    },
    nested2,
  }))
}

Very easy with immer:

produce(
  obj,
  draft => draft.arr.forEach(({ nested1, nested2 }) => { nested1.val = nested2.val }),
)

and of course with qim :heart: (not sure if this is the simplest way):

apply(
    ['arr', $each, $setContext('val2', select(['nested2', 'val'])), 'nested1', 'val'],
  (_, { val2 }) => val2[0],
  obj,
)

In fact there is one way to do it with immutad●t:

update(
  obj,
  'arr[:]',
  set('nested1.val', get('nested2.val')),
)

Maybe this is sufficient... I think I need some sleep...

nlepage commented 6 years ago

In fact, immutad●t is the shortest...

nlepage commented 6 years ago

Closing this