如何在 React.js 中按字母顺序对数组中的对象进行排序

Posted

技术标签:

【中文标题】如何在 React.js 中按字母顺序对数组中的对象进行排序【英文标题】:how to sort an object alphabetically within an array, in React.js 【发布时间】:2018-06-08 10:52:47 【问题描述】:

我正在使用 React.js 和 firebase 制作一个应用程序,用户可以在其中输入姓名和人的地址。

firebase 中的对象如下所示:

L1NSTjqA10Qc85d7Kcc - name: John Doe, - address: 1 Maple Ave

我已成功将名称和地址打印到 DOM 上,但我想按名称的字母顺序对其进行排序。

所以我的列表将如下所示:

Jane Doe - 34 Green Street
John Doe - 1 Maple Ave
Riley Smith - 3 Happy Street

到目前为止,这是我的 JSX,用于在父组件上映射对象数组时:

<ul>
  this.state.contacts.map((res)=> <List data=res/>)
</ul>

以防万一,这是我的 componentDidMount:

componentDidMount() 
  const dbRef = firebase.database().ref();

  dbRef.on("value", (firebaseData) => 
    const itemsArray = [];
    const itemsData = firebaseData.val();
    for (let itemKey in itemsData) 
      itemsArray.push(itemsData[itemKey])
    
    this.setState( contacts: itemsArray)
  )

我曾尝试从另一个堆栈溢出论坛执行以下操作,但没有成功:

const myData = [].concat(this.state.contacts)
  .sort((a,b)=> a.name > b.name
  .map((res)=> <List data=res/>);

【问题讨论】:

【参考方案1】:

您尝试排序然后映射的逻辑部分可以这样完成。

const myData = this.state.contacts
 .sort(function(a, b) 
  if(a.name.toLowerCase() < b.name.toLowerCase()) return -1;
  if(a.name.toLowerCase() > b.name.toLowerCase()) return 1;
  return 0;
 )
 .map((item, i) => <List key=i data=item />);

或者如果你想做得更短,你可以这样做。

const myData = this.state.contacts
 .sort((a, b) => a.name.localeCompare(b.name))
 .map((item, i) => <List key=i data=item />);

localeCompare function是String的方法

在你调用的方法中

dbRef.on("value", (firebaseData) => 
  this.setState( 
      contacts: Array.from(firebaseData.val()).sort((a, b) => a.name.localeCompare(b.name)))
  );

在您的 render 方法中执行以下操作

 render () 
    return (
      <ul>
       
        this.state.contacts.map((item, i) => <List key=i data=item />)
       
      </ul>
    );
 

这有帮助吗?

【讨论】:

如何将它添加到我的 JSX 中?我试图在“返回”中输入您的简短答案,但是,它给了我错误。我应该在渲染方法之后但在返回之前添加它吗?请指教,谢谢 没关系,我想通了:我把它放在渲染方法中,在返回之前,但在jsx中调用了变量。感谢您的帮助! 无论如何我确实更新了我的答案。如果此答案对您有所帮助,请考虑将标记作为您的答案。并竖起大拇指。干杯。 @AdeelImran 你不需要这样做:itemsArray = itemsArray.sort 因为.sort 正在更改数组in place。你不应该这样做:this.state.contacts.sort 因为你正在改变状态。这就是 OP 使用 [].concat 创建新数组的原因。 明白,我也更新了那部分代码。我仍然觉得[].concat 是一种老派的方法。所以我只是使用Array.from 并对结果进行排序。【参考方案2】:

不要不要在渲染方法中对数据进行排序!它会在每次渲染调用时对其进行排序。

要记住的另一件事是sort 正在执行manipulation on the array and not returning a new copy of the array。 来自文档:

注意数组是原地排序的,不做拷贝

这意味着你将改变 state 对象,这是一个很大的反应。 这就是您使用[].concat(this.state.contacts) 创建新数组的原因。 你可以用ES2015 spread syntax实现一个新数组:

const newArray = [...this.state.contacts];

无论如何,不​​要处理状态的副本和突变,而是在将数组存储到状态之前进行排序:

itemsArray.sort((a,b) => 
    return a.name > b.name;
);
this.setState(
    contacts: itemsArray
)

【讨论】:

它不会对sort 部分执行重新渲染,除非状态再次更新。仅当您更新渲染方法时。 这不正是我写的吗? “它将在每次渲染调用时执行此操作”。顺便说一句,render 方法没有更新(它是一个将被调用的函数)。作为对象的状态将被更新。 这很简单,你有一个函数 render 在那个函数里面你正在做一些排序。每次render 被调用时,您都会再次进行此排序(可能没有充分的理由)。 render 方法将在状态的每次更新时被调用,因此 OP 可能有其他可以更新的状态数据,这将触发 render 调用,该调用将对数组进行排序再次。就像我提到的,没有充分的理由。 我明白你的意思。道歉。我已经更新了我的答案。 @AdeelImran +1 不要忘记 .sort 正在改变数组。因此,如果您直接在 state 对象上的 render 内执行此操作,您将改变 state【参考方案3】:

非常简单的解决方案,只需 2 个函数即可对多列应用排序。

不需要 toLowerCase ,只需使用 "" 转换成字符串

只需创建这两个函数

compareBy(key) 
return function (a, b) 
  if (""+a[key]<(""+b[key])) return -1;
  if (""+a[key]>(""+b[key])) return 1;
  return 0;
;

sortBy(key) 
let arrayCopy = [...this.state.data];
arrayCopy.sort(this.compareBy(key));
//arrayCopy.reverse(); for descending
this.setState(data: arrayCopy);
 

//write this in th
onClick=() => this.sortBy('column name')

如果你想降序使用它是升序排序 arrayCopy.reverse()

它根据 ASCII 格式排序,所以字符串使用 toLowerCase

【讨论】:

【参考方案4】:

.sort((a, b) => parseFloat(a.sort) - parseFloat(b.sort))

【讨论】:

欢迎来到 Stack Overflow!虽然这段代码可以解决问题,including an explanation 解决问题的方式和原因确实有助于提高帖子的质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于如何在 React.js 中按字母顺序对数组中的对象进行排序的主要内容,如果未能解决你的问题,请参考以下文章

在结构中按频率对数组中的字母进行排序

如何在数据库表中按字母顺序对列进行排序? [关闭]

如何在 Laravel 中按字母顺序对记录进行排序

如何在 swift 中按字母顺序对 JSON 字符串进行排序?

如何在pyspark中按字母顺序对嵌套结构的列进行排序?

如何在C中按顺序对带有数字和字母的文件名进行排序?