Sort method and indexes

262 Views Asked by At

I'm trying fixed data table in my project.

But I have a problem about sorting.

Here I'm using this example: https://github.com/facebook/fixed-data-table/blob/master/examples/old/SortExample.js

It sorts by desc or asc. But I have problem about it.

For example when I first sort it by name,it brings this sorted array.

id:2 name:Mary

id:4 name:Mary

id:5 name:Mary

id:1 name:Anna

id:3 name:Anna

That is ok.But when I sort it again by name desc.It brings.

id:4 name:Mary

id:2 name:Mary

id:5 name:Mary

id:3 name:Anna

id:1 name:Anna

Ok it sort by name but the problem is:It change the index of the same values.For example it brings (id:4 name:Mary) to the first line.

But when I first sorted,it bringed (id:2 name:Mary).

Why it changes the same values indexes?

Is there a problem about sort method?

EDIT:here is my full code:

var FixedDataTable = require('fixed-data-table');
var React = require('react');

var Column = FixedDataTable.Column;
var Table = FixedDataTable.Table;

var SortTypes = {
  ASC: 'ASC',
  DESC: 'DESC',
};

function renderDate(/*object*/ cellData) {
  return <span>{cellData.toLocaleString()}</span>;
}

var SortExample = React.createClass({
  getInitialState() {
    return {
      rows: [{"id":"1","name":"Mary"},{"id":"2","name":"Felix"},
                   {"id":"3","name":"Mary"},{"id":"4","name":"Felix"},
                   {"id":"5","name":"Mary"},{"id":"6","name":"Felix"},
                   {"id":"7","name":"Mary"},{"id":"8","name":"Felix"},
                   {"id":"9","name":"Mary"},{"id":"10","name":"Felix"},
                   {"id":"11","name":"Mary"},{"id":"12","name":"Felix"},
                   {"id":"13","name":"Mary"},{"id":"14","name":"Felix"},
                   {"id":"15","name":"Mary"},{"id":"16","name":"Felix"},
                   {"id":"17","name":"Mary"},{"id":"18","name":"Felix"} ,
                   {"id":"19","name":"Mary"},{"id":"20","name":"Felix"}],sortBy: 'id',
      sortDir: null,
    };
  },

  _rowGetter(rowIndex) {
    return this.state.rows[rowIndex];
  },

  _sortRowsBy(cellDataKey) {
    var sortDir = this.state.sortDir;
    var sortBy = cellDataKey;
    if (sortBy === this.state.sortBy) {
      sortDir = this.state.sortDir === SortTypes.ASC ? SortTypes.DESC : SortTypes.ASC;
    } else {
      sortDir = SortTypes.DESC;
    }

    var rows = this.state.rows.slice();
    rows.sort((a, b) => {
      var sortVal = 0;
      if (a[sortBy] > b[sortBy]) {
        sortVal = 1;
      }
      if (a[sortBy] < b[sortBy]) {
        sortVal = -1;
      }

      if (sortDir === SortTypes.DESC) {
        sortVal = sortVal * -1;
      }

      return sortVal;
    });

    this.setState({
      rows,
      sortBy,
      sortDir,
    });
  },

  _renderHeader(label, cellDataKey) {
    return (
      <a onClick={this._sortRowsBy.bind(null, cellDataKey)}>{label}</a>
    );
  },

  render() {
    var sortDirArrow = '';

    if (this.state.sortDir !== null){
      sortDirArrow = this.state.sortDir === SortTypes.DESC ? ' ↓' : ' ↑';
    }

    return (
      <Table
        rowHeight={50}
        rowGetter={this._rowGetter}
        rowsCount={this.state.rows.length}
        headerHeight={50}
        width={1000}
        height={500}
        {...this.props}>
        <Column
          headerRenderer={this._renderHeader}
          label={'id' + (this.state.sortBy === 'id' ? sortDirArrow : '')}
          width={100}
          dataKey='id'
        />
        <Column
          headerRenderer={this._renderHeader}
          label={'First Name' + (this.state.sortBy === 'name' ? sortDirArrow : '')}
          width={200}
          dataKey='name'
        />

      </Table>
    );
  },
});









ReactDOM.render(
 <SortExample/>,
  document.getElementById('app')
)
2

There are 2 best solutions below

3
On

Unable to duplicate the problem.

The sorting function appears to work correctly and as expected.

Update: The snippet was modified to alternate sort direction on each call. However, the results were the same, i.e., the function works correctly and as expected. In addition, the FixedDataTable demo sorts hundreds of records any direction correctly.

The sorting function is found on lines 53-65:

var rows = this.state.rows.slice();
rows.sort((a, b) => {
     var sortVal = 0;
     if (a[sortBy] > b[sortBy]) {
          sortVal = 1;
     }
     if (a[sortBy] < b[sortBy]) {
        sortVal = -1;
     }
     if (sortDir === SortTypes.DESC) {
         sortVal = sortVal * -1;
     }
     return sortVal;
});

A test array sorted repeatedly always returns the same data in the same order:

  • 2, Mary
  • 4, Mary
  • 5, Mary
  • 1, Anna
  • 3, Anna
  • There could be a problem with OP's code (not shown) or how the sorted data is copied back to the original array, i.e., setState().

    Show the code snippet and click run to try.

    var i, sortBy, SortTypes, state,count=0;
    
    
    SortTypes = {
      ASC: 'ASC',
      DESC: 'DESC'
    };
    
    sortBy = 'name';
    
    
    function test( sortDir ) {
    
      var rows = state.rows.slice();
      rows.sort((a, b) => {
        var sortVal = 0;
        if (a[sortBy] > b[sortBy]) {
          sortVal = 1;
        }
        if (a[sortBy] < b[sortBy]) {
          sortVal = -1;
        }
        if (sortDir === SortTypes.DESC) {
          sortVal = sortVal * -1;
        }
        return sortVal;
      });
    
      count++;
      document.getElementById('stdout').innerHTML += 
        'SORT: ' + count + ' ' + sortDir + '\n' +JSON.stringify(rows, null, '  ') + '\n\n';
    }
    
    
    
    // example data
    state = {
      rows: [{
        id: '1',
        name: 'Anna'
      }, {
        id: '2',
        name: 'Mary'
      }, {
        id: '30',
        name: 'Anna'
      }, {
        id: '40',
        name: 'Mary'
      }, {
        id: '100',
        name: 'Mary'
      }]
    };
    
    
    for(i=0; i<4; i++) {
      test( 'ASC' );
      test( 'DESC' );
    }
    Results of sorting the test array multiple times:<br>
    
    <xmp id="stdout"></xmp>

    1
    On

    i thinks this will fix your problem, i used Lodash library

    `var data = [
       {
        id:1,
        name: "Anna"
      },
      {
        id:3,
        name: "Anna"
      },
      {
        id:2,
        name: "Mary"
      },
      {
        id:4,
        name: "Mary"
      },
      {
        id:5,
        name: "Mary"
      }
    ];
    var sortArray = _.sortBy(data, function(o) { return o.name; });
    var reverseSortArray = _.cloneDeep(sortArray).reverse();
    console.log("sort Array: ", sortArray);
    console.log("reverse Sort Array", reverseSortArray);`