kirkegaard
kirkegaard

Reputation: 1138

Sort an array of objects in React and render them

I have an array of objects containing some information. I am not able to render them in the order I want and I need some help with that. I render them like this:

this.state.data.map(
   (item, i) => <div key={i}> {item.matchID} {item.timeM} {item.description}</div>
)

Is it possible to sort them ascending with item.timeM in that map() function or do I have to sort them before I use map?

Upvotes: 85

Views: 352983

Answers (12)

Mukund Bondre
Mukund Bondre

Reputation: 9

this is the code i write

//this is the data
data=[
  { id: 1, name: 'John', age: 28 },
  { id: 2, name: 'Jane', age: 22 },
  { id: 3, name: 'Alex', age: 35 },
]

//when you want to sort by name
data.sort((a, b) => a.name.localeCompare(b.name));
console.log('data sort by their Name :',data);


//when you want to sort by age
data.sort((a, b) => a.age - b.age);
console.log('data sort by their Ages :',data);

this is the output of the program

data sort by their Name : [
  { id: 3, name: 'Alex', age: 35 },
  { id: 2, name: 'Jane', age: 22 },
  { id: 1, name: 'John', age: 28 }
]
data sort by their Ages : [
  { id: 2, name: 'Jane', age: 22 },
  { id: 1, name: 'John', age: 28 },
  { id: 3, name: 'Alex', age: 35 }
]

Upvotes: 0

Manos M
Manos M

Reputation: 21

You can use toSorted() instead of sort(). It will create a new array. Sort will mutate your state which isn't something you really want... so your code will look like this:

const sortedArr = this.state
   .toSorted((a, b) => a.itemM > b.itemM ? 1 : -1)
   .map((item, i) => 
       <div key={i}> {item.matchID} {item.timeM}{item.description}</div>
   );

Upvotes: 2

d1ous
d1ous

Reputation: 43

Use localeCompare for strings. For many alphabets, it's better to use the string.localeCompare method to properly sort letters like Ö.

For example, let's sort several countries in German:

let countries = ['Österreich', 'Andorra', 'Vietnam']
alert( countries.sort( (a, b) => a > b ? 1 : -1) )

In this case result of sorted array will be next: Andorra, Vietnam, Österreich (wrong)

alert( countries.sort( (a, b) => a.localeCompare(b) ) )

On the other hand: Andorra, Österreich, Vietnam (properly)

Upvotes: 4

boletus151
boletus151

Reputation: 300

I found a really good post: React: how to dynamically sort an array of objects

It´s for dropdown, but you can adapt it. The important thing is the way of sorting the array because, as it is explained in the post, react is not realizing about list changes, as the elements are the same.

const [currentList, setCurrentList] = useState(new Array());

const sorted = [...dataList].sort((a, b) => b["lotNumber"] - a["lotNumber"]).reverse();

setCurrentList(sorted);

Upvotes: 2

Atit More
Atit More

Reputation: 155

This approach worked for me

const list = [
  { price: 10, plan: 'a' },
  { price: 2, plan: 'b' },
  { price: 8, plan: 'c' }
];
this.setState({ planList: list.sort((a,b)=> a.price-b.price)  });


render(){
   return(){
      <div>
          this.state.planList !== undefined && this.state.planList !== null && 
          this.state.planList !== '' && this.state.planList.map((ele, index) => {
              return (
                 <div key={index}> {ele.price}{ele.plan}</div>
              )
          })
      </div>
  }
}

Thank You

Upvotes: -3

vandana
vandana

Reputation: 81

this.state.data.sort((a, b) => a.objKey > b.objKey ? 1:-1).map((objKey, index))

Upvotes: 8

ANKIT DETROJA
ANKIT DETROJA

Reputation: 2065

const list = [
  { qty: 10, size: 'XXL' },
  { qty: 2, size: 'XL' },
  { qty: 8, size: 'M' }
]

list.sort((a, b) => (a.qty > b.qty) ? 1 : -1)

console.log(list)

Out Put :

[
  {
    "qty": 2,
    "size": "XL"
  },
  {
    "qty": 8,
    "size": "M"
  },
  {
    "qty": 10,
    "size": "XXL"
  }
]

Upvotes: 19

Mμ.
Mμ.

Reputation: 8542

This might be what you're looking for:

// ... rest of code

// copy your state.data to a new array and sort it by itemM in ascending order
// and then map 
const myData = [].concat(this.state.data)
    .sort((a, b) => a.itemM > b.itemM ? 1 : -1)
    .map((item, i) => 
        <div key={i}> {item.matchID} {item.timeM}{item.description}</div>
    );

// render your data here...

The method sort will mutate the original array . Hence I create a new array using the concat method. The sorting on the field itemM should work on sortable entities like string and numbers.

Upvotes: 166

Praveen prav
Praveen prav

Reputation: 41

Chrome browser considers integer value as return type not boolean value so,

this.state.data.sort((a, b) => a.item.timeM > b.item.timeM ? 1:-1).map(
    (item, i) => <div key={i}> {item.matchID} {item.timeM} {item.description}</div>
)

Upvotes: 4

Arun K
Arun K

Reputation: 921

Try lodash sortBy

import * as _ from "lodash";
_.sortBy(data.applications,"id").map(application => (
    console.log("application")
    )
)

Read more : lodash.sortBy

Upvotes: 8

Vincenzo Centofanti
Vincenzo Centofanti

Reputation: 77

this.state.data.sort((a, b) => a.item.timeM > b.item.timeM).map(
    (item, i) => <div key={i}> {item.matchID} {item.timeM} {item.description}</div>
)

Upvotes: 8

Shubham Khatri
Shubham Khatri

Reputation: 281686

You will need to sort your object before mapping over them. And it can be done easily with a sort() function with a custom comparator definition like

var obj = [...this.state.data];
obj.sort((a,b) => a.timeM - b.timeM);
obj.map((item, i) => (<div key={i}> {item.matchID}  
                      {item.timeM} {item.description}</div>))

Upvotes: 24

Related Questions