Javascript 按字母顺序呈现名称列表,并按名称的第一个字符分组
我需要按字母顺序呈现姓名列表,并按每个姓名的起始字母分组。应该是这样的:Javascript 按字母顺序呈现名称列表,并按名称的第一个字符分组,javascript,reactjs,Javascript,Reactjs,我需要按字母顺序呈现姓名列表,并按每个姓名的起始字母分组。应该是这样的: **A** Anders Anton Angela **B** Brian Bernard **C** Carl 我当前的解决方案可以对对象中包含的所有名称进行排序,但在名称之前添加起始字母作为元素时遇到问题(例如,在“Anders”上方呈现“A”,在“Brian”上方呈现“B”) 当前解决方案: completeEmpList = empList .sort((a, b) => a.Name.loc
**A**
Anders
Anton
Angela
**B**
Brian
Bernard
**C**
Carl
我当前的解决方案可以对对象中包含的所有名称进行排序,但在名称之前添加起始字母作为元素时遇到问题(例如,在“Anders”上方呈现“A”,在“Brian”上方呈现“B”)
当前解决方案:
completeEmpList = empList
.sort((a, b) => a.Name.localeCompare(b.Name))
.map((emp) => (
<div> {emp.Name} </div>
))
completeEmpList=empList
.sort((a,b)=>a.Name.localeCompare(b.Name))
.map((emp)=>(
{emp.Name}
))
它最多只能处理300个元素的数据,因此在这种情况下优化并不重要。您可以尝试以下代码:
completeEmpList = empList
.sort((a, b) => a.Name.localeCompare(b.Name))
.map((emp, index, array) => (
<div>
{ array[index - 1].Name[0].localeCompare( emp.Name[0] ) === -1?
<p>** { emp.Name[0] } **</p>
}
{emp.Name}
</div>
))
let previousChar = ''
if (empList) {
completeEmpList = empList
.sort((a, b) => a.Name.localeCompare(b.Name))
.map((emp) => {
if (emp.Name.charAt(0) !== previousChar) {
previousChar = emp.Name.charAt(0)
return (
<div>
<div className='charElement' key={'c' + emp.Id}> emp.Name.charAt(0)}</div>
</div>
<div className='empName'>{emp.Name}</div>
</div>
</div>
)
} else {
return (
<div className='empName'>{emp.Name}</div>
)
}
})
completeEmpList=empList
.sort((a,b)=>a.Name.localeCompare(b.Name))
.map((emp、索引、数组)=>(
{array[index-1].Name[0].localeCompare(emp.Name[0])=-1?
**{emp.Name[0]}**
}
{emp.Name}
))
您可以先排序,然后使用reduce
创建一个对象,并根据每个名称的第一个字符对值进行分组
类示例扩展了React.Component{
建造师(道具){
超级(道具)
此.state={
项目:[{姓名:“卡尔”},{姓名:“安德斯”},{姓名:“安东”},{姓名:“布赖恩”},{姓名:“伯纳德”},{姓名:“安吉拉”}]
}
}
render(){
常量组=this.state.items
.sort((a,b)=>a.Name.localeCompare(b.Name))
.减少((r,e)=>{
const key=e.Name[0];
如果(!r[key])r[key]=[]
r[键]。按下(e);
返回r;
}, {});
回来
{Object.entries(组)
.map([键,值],i)=>{
回来
{key}
{value.map((item,j)=>{item.Name})
})}
}
}
ReactDOM.render(,document.querySelector(#app))
通过评论中的一些指导,我让它与以下代码一起工作:
completeEmpList = empList
.sort((a, b) => a.Name.localeCompare(b.Name))
.map((emp, index, array) => (
<div>
{ array[index - 1].Name[0].localeCompare( emp.Name[0] ) === -1?
<p>** { emp.Name[0] } **</p>
}
{emp.Name}
</div>
))
let previousChar = ''
if (empList) {
completeEmpList = empList
.sort((a, b) => a.Name.localeCompare(b.Name))
.map((emp) => {
if (emp.Name.charAt(0) !== previousChar) {
previousChar = emp.Name.charAt(0)
return (
<div>
<div className='charElement' key={'c' + emp.Id}> emp.Name.charAt(0)}</div>
</div>
<div className='empName'>{emp.Name}</div>
</div>
</div>
)
} else {
return (
<div className='empName'>{emp.Name}</div>
)
}
})
让previousChar=''
如果(雇主){
completeEmpList=雇员列表
.sort((a,b)=>a.Name.localeCompare(b.Name))
.map((emp)=>{
if(emp.Name.charAt(0)!==previousChar){
previousChar=emp.Name.charAt(0)
返回(
emp.Name.charAt(0)}
{emp.Name}
)
}否则{
返回(
{emp.Name}
)
}
})
考虑这一点的另一种方法是先进行一些数据处理,将数据转换为方便的格式,然后再创建视图。假设您知道如何从中生成视图,我认为一种有用的格式可能是数组数组,每个首字母有一个内部数组,类似于
[["Anders", "Angela", "Anton"], ["Bernard", "Brian"], ["Carl"]]
要创建它,您可以使用自定义解决方案,但有一个合理的抽象可能更容易编写。因此,这个版本创建了函数groupWith
,它接受一个函数,该函数本身接受两个连续的值,并响应它们是否属于同一个组,在这种情况下,只需(a,b)=>a.charAt(0)==b.charAt(0)
:
constgroupwith=(fn,list)=>list.slice(1).reduce(
(all,curr)=>fn(all[all.length-1][0],curr)
所有.slice(0,-1).concat([all[all.length-1].concat(curr)])
:all.concat([[curr]]),
[[列表[0]]]
)
常量名称=['Brian'、'Anders'、'Angela'、'Carl'、'Anton'、'Bernard'];
const groups=groupWith((a,b)=>a.charAt(0)==b.charAt(0),names.sort())
log(groups)
字符串不可更改性使其变得非常重要
我知道您说过优化并不重要,但是,我认为它在处理字符串时非常重要。原因是“不变性”。如果允许他们的算法在每次迭代时重新写入字符串,那么很容易得到二次摊销时间。使用集合,并使用必要的格式(换行符等)将字符串插入该集合是最便宜、最便宜的方法
const name=['Brian','Anders','Angela','Carl','Anton','Bernard'];
//创建一个以字母为键的灵长类哈希表。
//该键的值是名称的集合。
const memo=names.reduce((memo,name)=>{
if(memo中的名称[0])memo[name[0]].push(name);//如果名称中的第一个字母已被记录,则将其添加到该字母的集合中。
else memo[name[0]]=[name];//如果尚未将第一个字母添加到备忘录中,请添加该字母并为createa分配一个新的名称集合。
返回备忘录;
}, {});
console.log('memo:',memo)
//现在迭代你的记忆收藏。
//字符串是不可变的,因此使用单个单词的数组最适合
//最低运行时间。否则,您将有二次摊销时间。
常量应答=对象
.钥匙(备忘录)
.sort()//对备忘键进行排序以确保按字母顺序排列。
.reduce((a,字母)=>{//将备忘录{object}还原为数组。。。
const letterList=memo[letter]//创建新的名称数组。
.sort()//对名称数组进行排序。
.map((name)=>name);//将每个名称返回到数组中。
letterList.unshift(`**${letter}**`,'\n');//“unshift”将插入值放在集合的前面。
letterList.push('\n');//在数组末尾添加一个换行符以分隔各个字母组。
a=a.concat(letterList);//将完成的字母数组添加到所有名称的总体集合中。
返回a;
}, [])
.join('\n');//在newline上加入,这样您就不必由于不变性而重写整个字符串。
log('应答:\n',应答)代码>假设名称是字符串,排序后,您可以为它们编制索引