编辑: 方法groupBy,omit和mapValue从以下位置导入:
import groupBy from 'lodash/groupBy';
import mapValues from 'lodash/mapValues';
import omit from 'lodash/omit';
我有这个json
[{
"name": "Jitka",
"orderNumber": "1",
"order": false
},
{
"name": "Jitka",
"orderNumber": "0",
"order": false
},
{
"name": "Petr",
"orderNumber": "6",
"order": false
}]
在反应中,我需要按名称分组值。分组后,我需要将数据以格式打印到表中
我的代码是:
{
const ordersByName = groupBy(this.state && this.state.orders, 'name');
let order = mapValues(ordersByName, x => x.map(y => omit(y, 'name')));
this.state.sortedOrders.push(order);
}
return (
<div>
<MyNavbar/>
<div className="container">
<table className="table">
<tbody>
<tr>
<th>Name</th>
<th>Order number</th>
<th>Order</th>
</tr>
{this.state.sortedOrders.map((offer) => {
console.log(offer);
})}
</tbody>
</table>
</div>
</div>
谢谢。
答案 0 :(得分:0)
由于您实际上是在orderNumber
上进行分组,因此需要首先减少您的数据。因此,由于您已经在使用lodash,因此可以尝试执行以下操作:
let data = _(this.state.sortedOrders) // <-- chain this array via _.chain
.groupBy('name') // <-- group by name first
.mapValues(arr => // <-- map through the values of the object from groupBy
_.mergeWith( // <-- merge the grouped by name records
..._.sortBy(arr, 'orderNumber'), // <-- sort the array by `orderNumber`
(o, s, k) => _.isEqual(k, 'orderNumber') ? o + (s ? ',' + s : '') : o)
)
.values() // <-- get the values of the final object
.value() // <-- get the final result from the chaining
然后您的渲染将是:
<div>
<MyNavbar/>
<div className="container">
<table className="table">
<tbody>
<tr>
<th>Name</th>
<th>Order number</th>
<th>Order</th>
</tr>
{data.map(offer => (
<tr>
<td>{offer.name}</td>
<td>{offer.orderNumber}</td>
<td>{offer.order}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
简而言之,您需要让data
看起来像这样:
let data = [{ "name": "Jitka", "orderNumber": "1", "order": false }, { "name": "Jitka", "orderNumber": "0", "order": false }, { "name": "Petr", "orderNumber": "6", "order": false } ]
let result = _(data)
.groupBy('name')
.mapValues(arr =>
_.mergeWith(
..._.sortBy(arr, 'orderNumber'),
(o, s, k) => _.isEqual(k, 'orderNumber') ? o + (s ? ',' + s : '') : o)
)
.values()
.value()
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
您可以看到您有2条记录,而不是最初的3条记录,因为我们通过orderNumber
合并了其中两条。
这显然可以通过Array.reduce / Array.sort等完成,但是由于您已经在使用lodash,因此可以简单地利用其groupBy/mergeWith
等功能。
答案 1 :(得分:0)
此解决方案使用_.flow()
创建合并组功能。该函数接受一个iteratee(任何可以使用_.groupBy()
的iteratee),以及一个应作为数组收集的键列表。结果是一个新功能,该功能可以按迭代器分组,然后合并每个组,并合并collectKeys
中任何键的值:
const { flow, partialRight: pr, groupBy, map, mergeWith } = _; // simulates separate imports
const combineGroups = (iteratee, collectKeys) => flow(
pr(groupBy, iteratee),
pr(map, group => mergeWith({}, ...group, (t = [], s, k) =>
collectKeys.includes(k) ? [...t, s] : s)
)
);
const combineGroupsByName = combineGroups('name', ['orderNumber']);
const Demo = ({ orders }) => {
const ordersByName = combineGroupsByName(orders);
return (
<div className="container">
<table className="table">
<tbody>
<tr>
<th>Name</th>
<th>Order number</th>
<th>Order</th>
</tr>
{ordersByName.map(({ name, orderNumber, order }) => (
<tr>
<td>{name}</td>
<td>{orderNumber.sort().join(', ')}</td>
<td>{order.toString()}</td>
</tr>
))}
</tbody>
</table>
</div>
);
};
const orders = [{"name":"Jitka","orderNumber":"1","order":false},{"name":"Jitka","orderNumber":"0","order":false},{"name":"Petr","orderNumber":"6","order":false}];
ReactDOM.render(
<Demo orders={orders} />,
demo
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="demo"></div>