javascript - 根据条件向数组添加其他对象
问题描述
我正在尝试对以下对象数组进行排序:
var input = [
{ name: 'Trevor Hansen', group: 'Group 1' },
{ name: 'Britta Holt', group: 'Group 2' },
{ name: 'Jane Smith ', group: 'Group 2' },
{ name: 'Sandra Adams', group: 'Group 1' },
{ name: 'Ali Connors', group: 'Group 1' },
{ name: 'John Smith', group: 'Group 2' },
{ name: 'Sandra Williams', group: 'Group 2' },
{ name: 'Tucker Smith', group: 'Group 1' },
],
这应该是结果:
var result = [
{ header: 'Group 1' },
{ name: 'Sandra Adams', group: 'Group 1' },
{ name: 'Ali Connors', group: 'Group 1' },
{ name: 'Trevor Hansen', group: 'Group 1' },
{ name: 'Tucker Smith', group: 'Group 1' },
{ divider: true },
{ header: 'Group 2' },
{ name: 'Britta Holt', group: 'Group 2' },
{ name: 'Jane Smith ', group: 'Group 2' },
{ name: 'John Smith', group: 'Group 2' },
{ name: 'Sandra Williams', group: 'Group 2' },
],
对数组进行排序后,需要在每个组之前添加一个标题对象,然后在组之间添加一个分隔对象,但在新标题之前。
这是我当前的代码,用于对数组进行排序:
function compare(a, b) {
const valueA = a.group.toUpperCase();
const valueB = b.group.toUpperCase();
let comparison = 0;
if (valueA > valueB) {
comparison = 1;
} else if (valueA < valueB) {
comparison = -1;
}
return comparison;
}
array.sort(compare);
但是,如何在必要时在正确的位置添加标题和分隔符?
很感谢任何形式的帮助!
解决方案
我会用两个reduce()
链接在一起来解决它。
const input = [{
name: 'Trevor Hansen',
group: 'Group 1'
},
{
name: 'Britta Holt',
group: 'Group 2'
},
{
name: 'Jane Smith ',
group: 'Group 2'
},
{
name: 'Sandra Adams',
group: 'Group 1'
},
{
name: 'Ali Connors',
group: 'Group 1'
},
{
name: 'John Smith',
group: 'Group 2'
},
{
name: 'Sandra Williams',
group: 'Group 2'
},
{
name: 'Tucker Smith',
group: 'Group 1'
},
]
const groupItems = (arr) => {
return arr.reduce((a, c) => {
if (typeof a[c.group] === "undefined") a[c.group] = []
a[c.group] = [...a[c.group], c]
return a
}, {})
}
const step1 = groupItems(input)
console.log(step1)
const insertHeaders = (obj) => {
return Object.entries(obj).reduce((a, [key, vals], i, d) => {
let r = [{
header: key
},
...vals,
]
// this is needed to have the exact same array
// that you presented as desirable output:
// no divider at the last place
if (i < d.length - 1) {
r = [...r, {
divider: true
}]
}
a = [...a, ...r]
return a
}, [])
}
const step2 = insertHeaders(step1)
console.log(step2)
此解决方案的好处是您不需要了解有关输入的任何信息,只需知道它有一个attribute
命名的group
. 其他一切都是自动的:
- 组是根据
group
属性创建的 - 项目放置在标题之后和分隔符之前(最后一组除外 - 最后没有分隔符)
但这给我带来了一个问题:你为什么要创造array
这样的作品?在大多数情况下,以这种方式使用数组并不是最好的主意。组很容易用 表示object
,并且有一些函数可以迭代object
( for...in
、Object.entries
等)。如果您在 UI 中需要“标题”(例如表格元素等),最好将标题插入移动到代码的显示部分(与实际数据分离)并且仅在您创建视觉效果时应用。(当然:对你的情况不太了解,这个解决方案可能是完全明智的。:))
推荐阅读
- flutter - 颤振改造@Multipart注释的问题
- php - 动态 url(由斜杠分隔)参数获取数组?(例如:/category,cat1,cat2/types,type1,type2)
- android - 使用选择器更改时,浮动操作按钮图标未居中对齐
- javascript - 布局抖动会导致不正确的绘画吗?
- javascript - 如何从对象键数组中计算剩余值?
- python - 如何打开特定文件,并在下一行写入数据,而不是删除以前的数据?
- transactions - 在运行以太坊节点时,我收到此错误“”恐慌:运行时错误:无效的内存地址或无指针引用“
- backup - 用dd在img文件中备份我的覆盆子不起作用
- laravel-8 - Laravel Livewire 订单页面上的多个下拉项目(产品)选择问题
- javascript - 页面完全加载后执行不重要的 Javascript 文件