问题描述
我有一个对象,其参数包含对象的和数组。我收到1个对象ID,我需要在整个混乱中找到它的位置。通过过程性编程,我使其能够正常工作:
const opportunitiesById = {
1: [
{ id: 1, name: 'offer 1' },
{ id: 2, name: 'offer 1' }
],
2: [
{ id: 3, name: 'offer 1' },
{ id: 4, name: 'offer 1' }
],
3: [
{ id: 5, name: 'offer 1' },
{ id: 6, name: 'offer 1' }
]
};
const findObjectIdByOfferId = (offerId) => {
let opportunityId;
let offerPosition;
const opportunities = Object.keys(opportunitiesById);
opportunities.forEach(opportunity => {
const offers = opportunitiesById[opportunity];
offers.forEach((offer, index) => {
if (offer.id === offerId) {
opportunityId = Number(opportunity);
offerPosition = index;
}
})
});
return { offerPosition, opportunityId };
}
console.log(findObjectIdByOfferId(6)); // returns { offerPosition: 1, opportunityId: 3 }
然而,这并不美观,我想以一种函数的方式来实现。 我已经查看了Ramda,当我查看单个优惠数组时,我可以找到优惠,但我找不到一种方法来查看整个对象=>每个数组,以找到我的优惠的路径。
R.findIndex(R.propEq('id', offerId))(opportunitiesById[1]);
我需要知道路径的原因是,我随后需要使用新数据修改该报价,并将其更新回原来的位置。
感谢您的帮助
推荐答案
我会将您的对象转换成对。
举个例子,转换一下:
{ 1: [{id:10}, {id:20}],
2: [{id:11}, {id:21}] }
进入:
[ [1, [{id:10}, {id:20}]],
[2, [{id:11}, {id:21}]] ]
然后,您可以迭代该数组,并将每个报价数组缩减为您要查找的报价的索引。假设您正在寻找优惠#21,则上面的数组将变为:
[ [1, -1],
[2, 1] ]
然后返回第二个元素不等于-1
的第一个元组:
[2, 1]
我建议这样做:
数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">const opportunitiesById = {
1: [ { id: 10, name: 'offer 1' },
{ id: 20, name: 'offer 2' } ],
2: [ { id: 11, name: 'offer 3' },
{ id: 21, name: 'offer 4' } ],
3: [ { id: 12, name: 'offer 5' },
{ id: 22, name: 'offer 6' } ]
};
const findOfferPath = (id, offers) =>
pipe(
toPairs,
transduce(
compose(
map(over(lensIndex(1), findIndex(propEq('id', id)))),
reject(pathEq([1], -1)),
take(1)),
concat,
[]))
(offers);
console.log(findOfferPath(21, opportunitiesById));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {pipe, transduce, compose, map, over, lensIndex, findIndex, propEq, reject, pathEq, take, concat, toPairs} = R;</script>
然后您可以按照您认为合适的方式修改您的报价:
数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">const opportunitiesById = {
1: [ { id: 10, name: 'offer 1' },
{ id: 20, name: 'offer 2' } ],
2: [ { id: 11, name: 'offer 3' },
{ id: 21, name: 'offer 4' } ],
3: [ { id: 12, name: 'offer 5' },
{ id: 22, name: 'offer 6' } ]
};
const updateOffer = (path, update, offers) =>
over(lensPath(path), assoc('name', update), offers);
console.log(updateOffer(["2", 1], '', opportunitiesById));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {over, lensPath, assoc} = R;</script>