78

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?

fabpico
  • 2,628
  • 4
  • 26
  • 43
kirkegaard
  • 1,058
  • 2
  • 12
  • 32

10 Answers10

157

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.

Mμ.
  • 8,382
  • 3
  • 26
  • 36
24

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>))
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
18

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"
  }
]
ANKIT DETROJA
  • 1,948
  • 1
  • 17
  • 24
9
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>
)
brooksrelyt
  • 3,925
  • 5
  • 31
  • 54
8

Try lodash sortBy

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

Read more : lodash.sortBy

Arun K
  • 868
  • 10
  • 17
7
this.state.data.sort((a, b) => a.objKey > b.objKey ? 1:-1).map((objKey, index))
Mayur Prajapati
  • 5,454
  • 7
  • 41
  • 70
vandana
  • 71
  • 1
  • 1
4

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>
)
2

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)

d1ous
  • 23
  • 4
1

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);
boletus151
  • 211
  • 2
  • 5
-2

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

Atit More
  • 137
  • 7