简体   繁体   English

与Ramda合并具有深度嵌套键的两个数组

[英]Merge two arrays with deeply nested key with Ramda

I've recently started using Ramda to work with responses from JSONAPI. 我最近开始使用Ramda处理来自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. 我尝试了多种方法,例如map,pick和join,但是这些对象似乎并不想按照我希望的方式进行合并。 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. 如果存在没有匹配电话的用户,则该用户将按原样返回,没有included属性。 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. 这假定您可以在用户中包括整个phone.attributes对象。 If you need to include only the phoneNumber , it's only slightly more complex, replacing the obvious line with 如果您只需要包含phoneNumber ,则只需稍微复杂一点,用替换明显的行即可

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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