具有以下数据结构...
const branches = [
{ id: '1', brand: { id: 'A' }},
{ id: '2', brand: { id: 'B' }},
{ id: '3', brand: { id: 'A' }}
]
我想挑选独特的品牌...这很容易。
const pickBrands = RM.pipe(
RM.map(RM.prop('brand')),
RM.uniqBy(RM.prop('id'))
)
但是最终,我需要改变整个事情……
const brands = [
{ id: 'A', branches: ['1', '3'] },
{ id: 'B', branches: ['2'] },
]
我有点困惑,考虑到在第一张地图之后,我正在丢失有关分支的信息,我该如何处理呢?
答案 0 :(得分:2)
您可以将R.groupBy
与R.path
一起使用,按brand.id
进行分组,然后将R.toPairs
和R.map
与R.zipObject
一起使用,以生成新的组中的对象。
示例(由@ScottSauyet注释):
const { pipe, groupBy, path, map, pluck, toPairs, zipObj } = R
const fn = pipe(
groupBy(path(['brand', 'id'])), //=> {"A": [{brand: {id: "A"}, id: "1"}, {brand: {id: "A"}, id: "3"}], B: [{brand: {id: "B"}, id: "2"}]}
map(pluck('id')), //=> {A: ["1", "3"], B: ["2"]}
toPairs, //=> [["A", ["1", "3"]], ["B", ["2"]]]
map(zipObj(['id', 'brand']) ) //=> [{id: "A", brand: ["1", "3"]}, {id: "B", brand: ["2"]}]
)
const branches = [
{ id: '1', brand: { id: 'A' } },
{ id: '2', brand: { id: 'B' } },
{ id: '3', brand: { id: 'A' } }
]
const result = fn(branches)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
注意:我最初的解决方案使用的是R.applySpec({ id: head, branches: last })
,但似乎我是唯一一个更具可读性的解决方案。
答案 1 :(得分:2)
这可能也有帮助:
const group = R.pipe(
R.groupBy(R.path(['brand', 'id'])),
R.values,
R.map(
R.applySpec({
id: R.path([0, 'brand', 'id']),
branches: R.pluck('id'),
}),
),
);
const branches = [
{ id: '1', brand: { id: 'A' }},
{ id: '2', brand: { id: 'B' }},
{ id: '3', brand: { id: 'A' }}
];
console.log('group', group(branches));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
答案 2 :(得分:1)
您可以使用普通的旧JS来实现结果,使用带有findIndex的reduce来检查ID是否已存在,如果存在,则将ID推送到现有对象,否则,推送新对象:
const branches = [
{ id: '1', brand: { id: 'A' }},
{ id: '2', brand: { id: 'B' }},
{ id: '3', brand: { id: 'A' }}
]
console.log(branches.reduce((a, {id, brand}) => {
const i = a.findIndex(o => o.id === brand.id)
i + 1 ? a[i].branches.id.push(id) : a.push({id: brand.id, branches: { id: [id] }})
return a
}, []))
答案 3 :(得分:1)
尝试一下:
const branches = [
{ id: '1', brand: { id: 'A' }},
{ id: '2', brand: { id: 'B' }},
{ id: '3', brand: { id: 'A' }}
]
const groupBy = (branches) => branches.reduce((acc, ele)=>( (acc[ele.brand.id] = acc[ele.brand.id] || []).push(ele), acc),{})
const reformat = ([k, v]) =>({id: k, branches: {id:v.map(({id})=>id)}})
const result = Object.entries(groupBy(branches)).map(ele => reformat(ele))
console.log(result);
答案 4 :(得分:1)
您可以使用Map
来收集品牌。
const
branches = [{ id: '1', brand: { id: 'A' } }, { id: '2', brand: { id: 'B' } }, { id: '3', brand: { id: 'A' } }],
brands = Array.from(
branches.reduce((m, { id: branche, brand: { id } }) =>
m.set(id, [...(m.get(id) || []), branche]), new Map),
([id, branches]) => ({ id, branches: { id: branches }})
);
console.log(brands);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 5 :(得分:1)
首先让我们为品牌定义一个空模板:
const brandTmpl =
{ id: null,
branches: [] };
然后,我们定义一个函数,该函数返回给定branch
的品牌ID:
const brandId = path(['brand', 'id']);
brandId({ id: '1', brand: { id: 'A' }});
//=> 'A'
然后给定brand
和branch
,让我们定义一个将分支“添加”到品牌的函数:
const brand = (brd, bch) => (
{ id: brandId(bch),
branches: append(bch.id, brd.branches) });
brand(brandTmpl, { id: '1', brand: { id: 'A' }});
//=> {id: 'A', branches: ['1']}
现在让我们使用所有这些来按品牌合并分支:
const brands = reduceBy(brand, brandTmpl, brandId);
brands([
{ id: '1', brand: { id: 'A' }},
{ id: '2', brand: { id: 'B' }},
{ id: '3', brand: { id: 'A' }}]);
//=> { A: { id: "A", branches: ["1", "3"]},
//=> B: { id: "B", branches: ["2"]} }
最后,我们可以简单地提取值:
const branches = [
{ id: '1', brand: { id: 'A' }},
{ id: '2', brand: { id: 'B' }},
{ id: '3', brand: { id: 'A' }} ];
const brandId = path(['brand', 'id']);
const brandTmpl =
{ id: null,
branches: [] };
const brand = (brd, bch) => (
{ id: brandId(bch),
branches: append(bch.id, brd.branches) });
const brands = reduceBy(brand, brandTmpl, brandId);
const pickBrands = compose(values, brands);
console.log(
pickBrands(branches)
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {path, append, reduceBy, compose, values} = R;</script>