Use Ramda to find child index and corresponding parent index

56 Views Asked by At

I have 2 implementation which you can see below and I don't see how it can be simplified. Also, maybe I'm missing something about function composition here, I would be glad to get any help.

p.s.: It also would be nice to get rid of arrow functions.

const sections = [
  {
    key: 'first',
    data: [ { key: 'a' }, { key: 'b' } ]
  },
    {
    key: 'second',
    data: [ { key: 'c' }, { key: 'd' } ]
  },
  {
    key: 'third',
    data: [ { key: 'e' }, { key: 'f' } ]
  },
]
const pathToField = (key, sections) =>
  sections
    .reduce((found, section, parentIndex) =>
      compose(
        unless(equals(-1), pair(parentIndex)),
        findIndex(propEq(key, 'key')),
        prop('data')
      )(section)
    )

pathToField('f', sections)
const findKeyIndex = useWith(findIndex, [propEq(__, 'key'), prop('data')])

const findFieldIndex = curry(
  (key, sections) => compose(
    converge(pair, [prop('index'), findKeyIndex(key)]),
    find(compose(gt(__, -1), findKeyIndex(key))),
    addIndex(map)(flip(assoc('index')))
  )(sections)
)

findFieldIndex('f', sections)
1

There are 1 best solutions below

0
mandy8055 On

If I have to simplify this further(and also not use arrow functions) I would do something like:

Explanation of code:

  1. findKeyIndex: This utility function returns the index of an object with a given key in a data array. It uses R.findIndex, R.propEq, and R.prop to achieve this.

  2. R.addIndex(R.map)(R.flip(R.assoc('index'))): This part of the code adds an index property to each parent object in the sections array. The index property holds the index of the object in the sections array.

  3. R.find(R.compose(R.gt(R.__, -1), findKeyIndex(key))): This part finds the first parent object in the modified sections array where the key is found in its data array. The R.gt(R.__, -1) condition checks if the index returned by findKeyIndex(key) is greater than -1, meaning the key was found in the data array.

  4. R.converge(R.pair, [R.prop('index'), findKeyIndex(key)]): Finally, this part forms a pair of indices using the parent object's index property and the index of the object with the specified key in the data array. The result is returned as a pair of indices.

const sections = [{
    key: 'first',
    data: [{
      key: 'a'
    }, {
      key: 'b'
    }]
  },
  {
    key: 'second',
    data: [{
      key: 'c'
    }, {
      key: 'd'
    }]
  },
  {
    key: 'third',
    data: [{
      key: 'e'
    }, {
      key: 'f'
    }]
  },
];

const findKeyIndex = R.useWith(R.findIndex, [R.propEq(R.__, 'key'), R.prop('data')]);
const findFieldIndex = R.curry((key, sections) =>
  R.compose(
    R.converge(R.pair, [R.prop('index'), findKeyIndex(key)]),
    R.find(R.compose(R.gt(R.__, -1), findKeyIndex(key))),
    R.addIndex(R.map)(R.flip(R.assoc('index')))
  )(sections)
);

console.log(findFieldIndex('f', sections));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.29.0/ramda.min.js"></script>