67

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,075
  • 3
  • 22
  • 36
KimR
  • 948
  • 2
  • 10
  • 31

8 Answers8

139

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μ.
  • 7,834
  • 3
  • 25
  • 36
  • 1
    I think `.sort((a, b) => a.itemM > b.itemM)` is incorrect here (this really threw me off...). It should be `.sort((a, b) => a.itemM - b.itemM)` if `itemM` are numbers, right? – Bret Royster May 05 '20 at 23:05
  • 4
    If `itemM` not numbers it needs to be something more like this: `.sort((a, b) => a.item.timeM > b.item.timeM ? 1:-1)` – Bret Royster May 05 '20 at 23:13
  • great answer. It's also well worth being aware of `.localeCompare()`, for example `b.item.timeM.localeCompare(b.item.timeM)` – ErichBSchulz Sep 21 '21 at 13:22
22

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
  • 246,420
  • 52
  • 367
  • 373
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,762
  • 5
  • 28
  • 49
9

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,526
  • 15
  • 20
7

Try lodash sortBy

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

Read more : lodash.sortBy

Arun K
  • 760
  • 9
  • 15
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>
)
4
this.state.data.sort((a, b) => a.objKey > b.objKey ? 1:-1).map((objKey, index))
Mayur
  • 5,212
  • 7
  • 37
  • 65
vandana
  • 41
  • 1
-1

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
  • 109
  • 7