-1

i'm pretty new to ramdajs, however I do understand the concepts of functional programming so a little help with this challenge will set me off forward.

so I have two json responses related by a foreign Key relationship, carId in this case. where a car can have many colors.


Cars: 

[ [
  {
    name: { manufacture: 'toyatothon', year: '1830' },
    density: 1.14,
    id: '32ccfa8d-8db6-41f6-83fa-7726851bffd4',
    image: 'https://test.image/toyotathon',
    description: {
      type: 'typical toyotathon',
      style: 'stylish'

    }
  },
  {
    name: { manufacture: 'toyatothon', year: '1830' },
    density: 1.14,
    id: 'c7bc7177-8137-4552-a218-0aa4d2491373',
    image: 'https://test.image/toyotathon',
    description: {
      type: 'typical toyotathon',
      style: 'stylish'

    }
  },
... ]
*/

Colors:

[
  {
    id: '8f529b1f-18a8-408b-a88c-b9056ef6e50e',
    name: { color: 'blue', shade: 'black'},
    carId: 'c7bc7177-8137-4552-a218-0aa4d2491373',
    image: 'https://test.image/pla_standard'  },

  {
    id: 'b04458ec-ee2b-4ead-9f90-a2aa30608ea7',
    name: { color: 'blue', shade: 'black'' },
    carId: '32ccfa8d-8db6-41f6-83fa-7726851bffd4',
    image: 'https://test.image/toyotathon'
  },...]

desired output:

Cars:

[ [
  {
    name: { manufacture: 'toyatothon', year: '1830' },
    density: 1.14,
    id: '32ccfa8d-8db6-41f6-83fa-7726851bffd4',
    image: 'https://test.image/toyotathon',
    description: {
      type: 'typical toyotathon',
      style: 'stylish'

    }, 
    colors: [ 
      {
    id: 'b04458ec-ee2b-4ead-9f90-a2aa30608ea7',
    name: { en: 'Sanded', de: 'Geschliffen', es: 'Estándar' },
    carId: '32ccfa8d-8db6-41f6-83fa-7726851bffd4',
    image: 'https://test.image/toyotathon'
}, 
... // whatever other colors belonging to the same `carId` 
  ]}
  {
    name: { manufacture: 'toyatothon', year: '1830' },
    density: 1.14,
    id: 'c7bc7177-8137-4552-a218-0aa4d2491373',
    image: 'https://test.image/toyotathon',
    description: {
      type: 'typical toyotathon',
      style: 'stylish'

    },
    colors: [ 
      {
    id: 'b04458ec-ee2b-4ead-9f90-a2aa30608ea7',
    name: { en: 'Sanded', de: 'Geschliffen', es: 'Estándar' },
    carId: 'c7bc7177-8137-4552-a218-0aa4d2491373',
    image: 'https://test.image/toyotathon'
}, 
... // whatever other colors belonging to the same `carId` 
]
  },
... ]

code that I have written achieves the above output but only kinda imperatively is as follows:

    carsResponse.map((car) => {
      car['colors'] = [];
      colorsResponse.forEach((color) => {
        if (car.id == color.carId) {
          return car['colors'].push(color);
        }
      });
    });

I'm wondering how the above map with a forEach inside can be achieved using ramdajs.

Exodus Reed
  • 177
  • 1
  • 10

1 Answers1

1

We could do this using Ramda, with something like this:

const colorize = (colors) => 
  map ((car) => assoc ('color') (filter (eqProps ('carId') (car)) (colors)) (car))


const cars = [{id: '8f529b1f-18a8-408b-a88c-b9056ef6e50e', name: { color: 'blue', shade: 'black'}, carId: 'c7bc7177-8137-4552-a218-0aa4d2491373', image: 'https://test.image/pla_standard'}, {id: 'b04458ec-ee2b-4ead-9f90-a2aa30608ea7', name: {color: 'blue', shade: 'black'}, carId: '32ccfa8d-8db6-41f6-83fa-7726851bffd4', image: 'https://test.image/toyotathon'}]
const colors = [{id: '8f529b1f-18a8-408b-a88c-b9056ef6e50e', name: {color: 'blue', shade: 'black'}, carId: 'c7bc7177-8137-4552-a218-0aa4d2491373', image: 'https://test.image/pla_standard'}, {id: 'b04458ec-ee2b-4ead-9f90-a2aa30608ea7', name: {color: 'blue', shade: 'black'}, carId: '32ccfa8d-8db6-41f6-83fa-7726851bffd4', image: 'https://test.image/toyotathon'}]

console .log (colorize (colors) (cars))
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js"></script>
<script> const {map, assoc, filter, eqProps} = R </script>

and if we tried hard enough, adding some flips and composes and perhaps a chain or ap or two, we could get this to an entirely point-free version.

But I see no advantage in that over this vanilla JS version:

const colorize = (cars) => (colors) => cars .map ((car) => ({
  ...car,
  colors: colors .filter ((color) => color .carId == car .carId)
}))

const cars = [{id: '8f529b1f-18a8-408b-a88c-b9056ef6e50e', name: { color: 'blue', shade: 'black'}, carId: 'c7bc7177-8137-4552-a218-0aa4d2491373', image: 'https://test.image/pla_standard'}, {id: 'b04458ec-ee2b-4ead-9f90-a2aa30608ea7', name: {color: 'blue', shade: 'black'}, carId: '32ccfa8d-8db6-41f6-83fa-7726851bffd4', image: 'https://test.image/toyotathon'}]
const colors = [{id: '8f529b1f-18a8-408b-a88c-b9056ef6e50e', name: {color: 'blue', shade: 'black'}, carId: 'c7bc7177-8137-4552-a218-0aa4d2491373', image: 'https://test.image/pla_standard'}, {id: 'b04458ec-ee2b-4ead-9f90-a2aa30608ea7', name: {color: 'blue', shade: 'black'}, carId: '32ccfa8d-8db6-41f6-83fa-7726851bffd4', image: 'https://test.image/toyotathon'}]

console .log (colorize (cars) (colors))
.as-console-wrapper {max-height: 100% !important; top: 0}

... and I'm a founder and principal author of Ramda. I'm still a fan, but I think there is too much emphasis on trying to do this with Ramda. It's a tool. Use it when it makes your code easier to understand, skip it when it doesn't.

Scott Sauyet
  • 49,207
  • 4
  • 49
  • 103
  • thanks a lot, very neat solution. i'm curious though, if I were to add another level to the chain where each `color` can have it's own array of let's say `shades`. is there a way to do it in the same chain ? I tried chaining another `map` at the end of the `colors` filter but it seems that now `colors` are coming back empty – Exodus Reed Sep 06 '22 at 19:44
  • figured it out, i wasn't returning `filter` of colors. I'll go ahead and remove the update – Exodus Reed Sep 06 '22 at 20:32