Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 按字母顺序呈现名称列表,并按名称的第一个字符分组_Javascript_Reactjs - Fatal编程技术网

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',应答)假设名称是字符串,排序后,您可以为它们编制索引