与Ramda

时间:2018-07-02 18:49:58

标签: javascript arrays object ramda.js

我最近开始使用Ramda处理来自JSONAPI的响应。对于应该如何使用深度嵌套的键合并两个对象,我有些困惑。

例如:

获取这两套数据,

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"
     },
];

我要创建的是一个新阵列,将相关手机添加到用户阵列中,并使用一个包含所有相关对象的新键,例如:

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"
    }
  }
]

我尝试了多种方法,例如map,pick和join,但是这些对象似乎并不想按照我想要的方式进行合并。下面的代码将这两个对象放入同一数组中,但是我似乎无法将下一步继续前进。

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

1 个答案:

答案 0 :(得分:0)

这是我的第一种方法:

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>

此版本适当处理了两个列表中的缺失值。如果有没有匹配电话的用户,则该用户将按原样返回,没有included属性。而且,如果有一部电话没有匹配的用户,那么它将被忽略。

这假定您可以在用户中包括整个phone.attributes对象。如果您只需要包含phoneNumber,则只需稍微复杂一点,将明显的行替换为

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