Ada_lovelace
Ada_lovelace

Reputation: 697

React.js - Sorting of nested arrays

My payload has the following data :

[
  {
    reports: [
      { title: 'Nio', active: True },
      { title: 'Nikola', active: False },
      { title: 'Tesla', active: True },
    ],
    dashboard_title: 'EV',
    created_on: 1653263788,
    ranking:4
  },
  {
    reports: [
      { title: 'corolla', active: True },
      { title: 'camry', active: True },
      { title: 'Volkswagen Golf GTI', active: True },
    ],
    dashboard_title: 'affordable',
    created_on: 154363788,
    ranking: 2
  },
  {
    reports: [
      { title: 'bmw z4', active: True },
      { title: 'Chevrolet Corvette', active: True },
      { title: 'porsche', active: True },
    ],
    dashboard_title: 'sports',
    created_on: 154363788,
    ranking: 1
  },
];

and I need to first sort this payload by ranking, for reports array nested - I need to sort reports in each category by title:

Here is my action:

export const getCategories = (param) => async (dispatch) => {
  const res = await axios.get(`{api}/dahsboard?{params}`, {
    headers: {},
  });
  const { data } = res;
  const data = data.sort(function (a, b) {
    return a.ranking - b.ranking;
  });
  let i;
  for (i = 0; i < data.length; i++) {
    data[i].reports = data[i].reports.sort((a, b) =>
      a.title.localeCompare(b.title)
    );
  }
  dispatch({
    type: DASHBOARD,
    payload: data,
  });
};

but this ain't working? is there any clean way to do it?

Upvotes: 1

Views: 1354

Answers (4)

akhtarvahid
akhtarvahid

Reputation: 9769

Sorted list based on ranking and reports

let data = [
  {
    reports: [
      { title: 'Nio', active: true },
      { title: 'Nikola', active: false },
      { title: 'Tesla', active: true },
    ],
    dashboard_title: 'EV',
    created_on: 1653263788,
    ranking: 4
  },
  {
    reports: [
      { title: 'corolla', active: true },
      { title: 'aamry', active: true },
     { title: 'Volkswagen Golf GTI', active: true },
    ],
    dashboard_title: 'affordable',
    created_on: 154363788,
    ranking: 2
  },
  {
    reports: [
      { title: 'bmw z4', active: true },
      { title: 'Chevrolet Corvette', active: true },
      { title: 'aporsche', active: true },
    ],
    dashboard_title: 'sports',
    created_on: 154363788,
    ranking: 1
  },
];

let sortedResult = data.sort((a,b)=> {
    if(a.ranking > b.ranking)
    return 1;
    else if(a.ranking < b.ranking)
    return -1;
    
    return 0;
}).map(list=> 
({...list, reports: list.reports.sort((a,b)=>(a.title.toLowerCase() > b.title.toLowerCase()) ? 1 : ((b.title.toLowerCase() > a.title.toLowerCase()) ? -1 : 0)
 )
 }))

console.log(sortedResult);

Upvotes: 0

gaetanoM
gaetanoM

Reputation: 42044

While sorting on ranking you can use a dummy property (you remove at the end) in order to sort reports by title:

var data = [
    {
        reports: [
            {title: 'Nio', active: true},
            {title: 'Nikola', active: false},
            {title: 'Tesla', active: true}
        ],
        dashboard_title: 'EV',
        created_on: 1653263788,
        ranking: 4
    },
    {
        reports: [
            {title: 'corolla', active: true},
            {title: 'camry', active: true},
            {title: 'Volkswagen Golf GTI', active: true}
        ],
        dashboard_title: 'affordable',
        created_on: 154363788,
        ranking: 2
    },
    {
        reports: [
            {title: 'bmw z4', active: true},
            {title: 'Chevrolet Corvette', active: true},
            {title: 'porsche', active: true}
        ],
        dashboard_title: 'sports',
        created_on: 154363788,
        ranking: 1
    },
];

data.sort(function (a, b) {
    if (a.reportsIsSorted == undefined) {
        a.reportsIsSorted = true;
        a.reports.sort(function(a, b) {
            return a.title.localeCompare(b.title);
        })
    }
    if (b.reportsIsSorted == undefined) {
        b.reportsIsSorted = true;
        b.reports.sort(function(a, b) {
            return a.title.localeCompare(b.title);
        })
    }
    return a.ranking - b.ranking;
}).forEach(e => delete e.reportsIsSorted);


console.log(data);
.as-console-wrapper {
   max-height: 100% !important;
}

Upvotes: 1

Boussadjra Brahim
Boussadjra Brahim

Reputation: 1

Try to chain a map function to the first sort and create another variable called items that has the new value:

  const { data } = res;
 let items = [...data].sort(function (a, b) {
    return a.ranking - b.ranking;
  }).map(item=>{
     item.reports.sort((a, b) =>a.title.localCompare(b.title))
     return item;
    });

dispatch({
    type: DASHBOARD,
    payload: items ,
  });

Upvotes: 2

radulle
radulle

Reputation: 1525

I suggest using map and sort like this:

const data = [
  {
    reports: [
      { title: "Nio", active: true },
      { title: "Nikola", active: false },
      { title: "Tesla", active: true },
    ],
    dashboard_title: "EV",
    created_on: 1653263788,
    ranking: 4,
  },
  {
    reports: [
      { title: "corolla", active: true },
      { title: "camry", active: true },
      { title: "Volkswagen Golf GTI", active: true },
    ],
    dashboard_title: "affordable",
    created_on: 154363788,
    ranking: 2,
  },
  {
    reports: [
      { title: "bmw z4", active: true },
      { title: "Chevrolet Corvette", active: true },
      { title: "porsche", active: true },
    ],
    dashboard_title: "sports",
    created_on: 154363788,
    ranking: 1,
  },
]

const sorted = data
  .sort((a, b) => a.ranking - b.ranking)
  .map((e) => ({ ...e, reports: e.reports.sort((a, b) => a.title - b.title) }))

console.log(sorted)

Upvotes: 1

Related Questions