简体   繁体   中英

Merge two arrays with deeply nested key with Ramda

I've recently started using Ramda to work with responses from JSONAPI. I am a bit confused as to how I should be merging two objects by a deeply nested key.

For example:

Take these two sets of data,

const users = [
    {   id: 1, 
        attributes: {
            firstName: "Bob",
            lastName: "Lee"
        }, 
        relationships: {
            phone: {
                data: {
                    id: 2, 
                    type: "phone"
                }
            }
        },
        type: "users"
     },
    {   id: 2, 
        attributes: {
            firstName: "Kevin",
            lastName: "Smith"
        }, 
        relationships: {
            phone: {
                data: {
                    id: 5, 
                    type: "phone"
                }
            }
        },
        type: "users"
     },
];

const phones= [
    {   id: 2, 
        attributes: {
            phoneNumber: "123-345-6789"
        },
        type: "phones"
     },
    {   id: 5, 
        attributes: {
            phoneNumber: "987-654-4321"
        }, 
        type: "phones"
     },
];

What I want to create is a new array with the related phone added to the user array with a new key holding all related objects, like this:

const newUser = 
[
  { id: 1,
    attributes: {
      firstName: "Bob",
      lastName: "Lee"
    },
    relationships: {
      phone: {
        data: {
          id: 2,
          type: "phones"
        }
      }
    },
    included: {
      phoneNumber: "123-345-6789"
    }
  },
  { id: 2,
    attributes: {
      firstName: "Kevin",
      lastName: "Smith"
    },
    relationships: {
      phone: {
        data: {
          id: 5,
          type: "phones"
        }
      }
    },
    type: "users",
    included: {
      phoneNumber: "987-654-4321"
    }
  }
]

I've tried multiple methods like map, pick, and join but the objects just don't seem to want to merge the way I want them to. The following code puts both of the objects into the same array, but I can't seem to wrap my head around where to go next.

const data = R.pipe(
        R.juxt([
          R.pipe(R.path(['users'])),
          R.pipe(R.path(['phones']))
        ]),
      )
}),

Here's my first approach:

 const {map, path, find, propEq, assoc} = R const addPhones = (phones, users) => map(user => { const phoneId = path(['relationships', 'phone', 'data', 'id'], user) const phone = find(propEq('id', phoneId), phones) return phone ? assoc('included', phone.attributes, user) : user }, users) const users = [{"attributes": {"firstName": "Bob", "lastName": "Lee"}, "id": 1, "relationships": {"phone": {"data": {"id": 2, "type": "phone"}}}, "type": "users"}, {"attributes": {"firstName": "Kevin", "lastName": "Smith"}, "id": 2, "relationships": {"phone": {"data": {"id": 5, "type": "phone"}}}, "type": "users"}, {"attributes": {"firstName": "Nancy", "lastName": "Johnson"}, "id": 3, "relationships": {"phone": {"data": {"id": 6, "type": "phone"}}}, "type": "users"}] const phones= [{"attributes": {"phoneNumber": "123-345-6789"}, "id": 2, "type": "phones"}, {"attributes": {"phoneNumber": "987-654-4321"}, "id": 5, "type": "phones"}, {"attributes": {"phoneNumber": "212-867-5309"}, "id": 7, "type": "phones"}] console.log(addPhones(phones, users)) 
 <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script> 

This version deals appropriately with missing values in either list. If there is a user with no matching phone, the user is returned as-is, with no included property. And if there is a phone with no matching user, it is simply ignored.

This makes the assumption that you can include the entire phone.attributes object in your user. If you need to include only the phoneNumber , it's only slightly more complex, replacing the obvious line with

    ? assocPath(['included', 'phoneNumber'], phone.attributes.phoneNumber, user)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM