1

I am trying to get values from nested arrays using Ramda. I have multiple groups like in the example below. I need to get all children from all sections and all childrenWithoutSections in one array of strings.

const groups = [
   {
      "id":"10",
      "sections":[
         {
            "id":"1",
            "children":["10", "11"]
         },
         {
            "id":"2",
            "children":["12"]
         }
      ],
      "childrenWithoutSections":["1", "2"]
   },
   {
      "id":"11",
      "sections":[
         {
            "id":"3",
            "children":["13", "14"]
         },
         {
            "id":"4",
            "children":["15"]
         }
      ],
      "childrenWithoutSections":["3", "4"]
   }
]

I started with something like this:

R.pipe(
  R.pluck(['childrenWithoutSections']),
  R.flatten
)(groups)

And as a result, I got all the children from one required key but I have no idea how to get nested values from sections/children?

3
  • Anything wrong with simply doing groups .flatMap (g => [... g .sections .flatMap (s => s.children), ... g . childrenWithoutSections]) ? Commented Jan 12, 2022 at 20:12
  • Unfortunately, I need to support IE11 :/ Probably I can find some polyfills to use it there but using Ramda is easier. Commented Jan 12, 2022 at 20:17
  • 1
    This is similar: R .chain (g => R .chain (s => s.children, g .sections) .concat (g . childrenWithoutSections), groups) Commented Jan 12, 2022 at 20:29

2 Answers 2

2

As well as the suggestions in the comments, we can also write a point-free version of this:

const extract = chain (
  lift (concat) (
    pipe (prop ('sections'), pluck ('children'), flatten), 
    prop ('childrenWithoutSections')
  )
)

const groups = [{id: "10", sections: [{id: "1", children: ["10", "11"]}, {id: "2", children: ["12"]}], childrenWithoutSections: ["1", "2"]}, {id: "11", sections: [{id: "3", children: ["13", "14"]}, {id: "4", children: ["15"]}], childrenWithoutSections: ["3", "4"]}]

console .log (extract (groups))
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.2/ramda.min.js"></script>
<script> const {chain, lift, concat, pipe, prop, pluck, flatten} = R     </script>

Sign up to request clarification or add additional context in comments.

1 Comment

As always exactly what I needed. Thank you for your help.
2

Another option is to use R.juxt to get children from the sections, and the childrenWithoutSections and then flattening the results. By chaining the results we get the array of values.

const {chain, pipe, juxt, prop, pluck, flatten } = R 

const fn = chain(pipe(
  juxt([
    pipe(prop('sections'), pluck('children')),
    prop('childrenWithoutSections')
  ]),
  flatten,
))

const groups = [{id: "10", sections: [{id: "1", children: ["10", "11"]}, {id: "2", children: ["12"]}], childrenWithoutSections: ["1", "2"]}, {id: "11", sections: [{id: "3", children: ["13", "14"]}, {id: "4", children: ["15"]}], childrenWithoutSections: ["3", "4"]}]

const result = fn(groups)

console.log(result)
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.2/ramda.min.js"></script>

2 Comments

Nice! There's so often more than one good way to do these things.
I must say you two always have great ways to do these things... So thank you both :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.