使用 Ramda 合并两个具有深度嵌套键的数组
Merge two arrays with deeply nested key with Ramda
我最近开始使用 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"
},
];
我想要创建的是一个新数组,将相关 phone 添加到用户数组,并使用一个新键保存所有相关对象,如下所示:
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"
}
}
]
我已经尝试了多种方法,例如映射、选择和连接,但对象似乎并不想按照我希望的方式合并。下面的代码将两个对象放入同一个数组中,但我似乎无法确定下一步该去哪里。
const data = R.pipe(
R.juxt([
R.pipe(R.path(['users'])),
R.pipe(R.path(['phones']))
]),
)
}),
这是我的第一种方法:
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>
此版本适当地处理了任一列表中的缺失值。如果没有匹配 phone 的用户,则按原样返回该用户,没有 included
属性。如果 phone 没有匹配的用户,它会被忽略。
这假设您可以在用户中包含整个 phone.attributes
对象。如果您只需要包含 phoneNumber
,它只会稍微复杂一些,将明显的行替换为
? assocPath(['included', 'phoneNumber'], phone.attributes.phoneNumber, user)
我最近开始使用 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"
},
];
我想要创建的是一个新数组,将相关 phone 添加到用户数组,并使用一个新键保存所有相关对象,如下所示:
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"
}
}
]
我已经尝试了多种方法,例如映射、选择和连接,但对象似乎并不想按照我希望的方式合并。下面的代码将两个对象放入同一个数组中,但我似乎无法确定下一步该去哪里。
const data = R.pipe(
R.juxt([
R.pipe(R.path(['users'])),
R.pipe(R.path(['phones']))
]),
)
}),
这是我的第一种方法:
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>
此版本适当地处理了任一列表中的缺失值。如果没有匹配 phone 的用户,则按原样返回该用户,没有 included
属性。如果 phone 没有匹配的用户,它会被忽略。
这假设您可以在用户中包含整个 phone.attributes
对象。如果您只需要包含 phoneNumber
,它只会稍微复杂一些,将明显的行替换为
? assocPath(['included', 'phoneNumber'], phone.attributes.phoneNumber, user)