0

I have Items data which I am attempting to display array values sorted by cost field in costtable array when roomname is Double and type is 2.Here is my code:

Json:

    {
        "index": 1,
        "id": "5e3961face022d16a03b1de9_1023632_1004876",
        "costtable": [
            {
                "roomname": "Single",
                "room_id": "1023632_479490,1004876_385485",
                "family": [
                    {
                        "title": "adult 1",
                        "cost": 3.7568000,
                        "unit": "10",
                        "type": "2"
                    }
                ]
            }
        ]
    },
    {
        "index": 2,
        "id": "5e3961face022d16a03b1de9_1088496_1005362",
        "costtable": [
            {
                "roomname": "Double",
                "room_id": "1088496_447339,1005362_415279",
                "family": [
                    {
                        "title": "adult 1",
                        "cost": 5.6868000,
                        "unit": "10",
                        "type": "2"
                    }
                ]
            }
        ]
    },
    {
        "index": 3,
        "id": "5e3961face022d16a03b1de9_1141859_1005529",
        "costtable": [
            {
                "roomname": "Single",
                "room_id": "1141859_74888,1005529_870689",
                "family": [
                    {
                        "title": "adult 1",
                        "cost": 5.9586000,
                        "unit": "10",
                        "type": "2"
                    }
                ]
            }
        ]
    }
]

Code:

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            Items: [],
            library: null,
            perPage: 20,
            currentPage: 1,
            maxPage: null,

        }
    }
    componentDidMount() {
        fetch('/json', {
            method: 'GET',
        })
            .then(response => response.text())
            .then(text => {
                let Maindata = JSON.parse(text.replace(/\'/g, '"'))
                let CostSort = Maindata.map(a => {
                    return this.renderSort(a)
                })
                Maindata.sort((a, b) => a.CostSort - b.CostSort);
                this.setState(state => ({
                    ...state,
                    Items: Maindata
                }), () => {
                    this.reorganiseLibrary()
                })
            }).catch(error => console.error(error))

    }
    reorganiseLibrary = () => {
        const { perPage, Items } = this.state;
        let library = Items;
        library = _.chunk(library, perPage);
        this.setState({
            library,
            currentPage: 1,
            maxPage: library.length === 0 ? 1 : library.length
        });
    };

    renderSort(element) {
        let indents = []
        let lenFamilies = element.costtable.length
        for (let i = 0; i < lenFamilies; i++) {
            if (element.costtable[i].roomname.indexOf('Double') > -1) {
                for (let j = 0; j < element.costtable[i].family.length; j++) {
                    if (element.costtable[i].family[j].type == 2) {
                        indents.push(element.costtable[i].family[j].cost)
                        break;
                    }
                }
                break;
            }
        }
        return (indents)

    }

    // Previous Page
    previousPage = event => {
        this.setState({
            currentPage: this.state.currentPage - 1
        });
    };
    // Next Page 
    nextPage = event => {
        this.setState({
            currentPage: this.state.currentPage + 1
        });
    };



    // handle per page
    handlePerPage = (evt) =>
        this.setState({
            perPage: evt.target.value
        }, () => this.reorganiseLibrary());

    // handle render of library
    renderLibrary = () => {
        const { library, currentPage } = this.state;
        if (!library || (library && library.length === 0)) {
            return '';
        }
        return library[currentPage - 1].map((item, i) => (
            <div className="item-list">
                {item.index}
            </div>
        ));
    };
    render() {
        const { library, currentPage, perPage, maxPage } = this.state;
        return (
            <div>
                <div className="wrapper-data">
                    {this.renderLibrary()}
                </div>
                <div class="clr"></div>
                <ul id="page-numbers">
                    <li className="nexprevPage">
                        {currentPage !== 1 && (
                            <button onClick={this.previousPage}><span className="fa-backward"></span></button>
                        )}
                    </li>
                    <li className="controlsPage active">{this.state.currentPage}</li>
                    <li className="restControls">...</li>
                    <li className="controlsPage">{this.state.maxPage}</li>
                    <li className="nexprevPage">
                        {(currentPage < maxPage) && (<button onClick={this.nextPage}><span className="fa-forward"></span></button>
                        )}
                    </li>
                </ul>
            </div>
        );
    }

}
ReactDOM.render(<App />, document.getElementById('Content'));

This code does not give me any errors but displays the values in an unsorted format. How can I sort it?

New Code

  Maindata.sort((a, b) => {
            let lenFamilies = a.costtable.length
            for (let i = 0; i < lenFamilies; i++) {
                if( a.costtable[i].roomname.indexOf('Double') > -1){
                    for (let j = 0; j < a.costtable[i].family.length; j++) {
                        if( a.costtable[i].family[j].type == 2){

                        a.costtable[i].family[j].cost- b.costtable[i].family[j].cost
                        }
                    }
                }
            }
        }

2 Answers 2

1

I do not understand the exact formula that you are using to sort, but what you are doing before the sort is wrong.

In your componentDidMount

let CostSort = Maindata.map(a => { return this.renderSort(a) })

This returns an array into a variable called CostSort and does not affect MainData in any way.

However, later on you do this.

Maindata.sort((a, b) => a.CostSort - b.CostSort);

For first iteration, this will compare Maindata[0] and Maindata[1]. Note that there is no CostSort in either of the objects and hence you are performing operation of undefined - undefined which is NaN. Therefore no sorting happens.

I would suggest you use only the sort function and do your comparison between two values there.

Maindata.sort((a, b) => {
 // Do your calculation here

 if(a should be before b) {
    return -1;
  } else {
    return 1;
  }
}

P.S The convention for variable in js is camelCase and not PascalCase. So, Maindata should he mainData.

EDIT: Here is a simple sort implementation which works for the above case, you can expand on it according to your full use case.

Maindata.sort((a, b) => {
  let lenFamilies = a.costtable.length;
  for (let i = 0; i < lenFamilies; i++) {
    if (
      a.costtable[i].roomname.includes("Double") &&
      !b.costtable[i].roomname.includes("Double")
    ) {
      return -1;
    }
    if (
      !a.costtable[i].roomname.includes("Double") &&
      b.costtable[i].roomname.includes("Double")
    ) {
      return 1;
    }
    if (a.costtable[i].roomname.indexOf("Double") > -1) {
      for (let j = 0; j < a.costtable[i].family.length; j++) {
        if (a.costtable[i].family[j].type == 2) {
          a.costtable[i].family[j].cost - b.costtable[i].family[j].cost;
        }
      }
    }
  }
});
Sign up to request clarification or add additional context in comments.

9 Comments

Thanks @Hassaan Tauqir for your answer, but how can I access to costtablearray in Maindata.sort((a, b) => {}) and do my calculation ?
I did what you said in New Code part but displays the values in an unsorted format yet!
@Maya a and b are objects from your array of Maindata, therefore, you can access costtable using a.costtable and b.costtable. Try using console.log(a, b) in the sort and you will see the object in your browser console
@Hassaan Tauqir Yes I can see the object in my browser console and if you take look at New Code part of my code I can see a.costtable[i].family[j].cost also in my browser console but values are not in an unsorted format
Can you give me detailed info as to how you want to sort your array, so I can make up a solution. I am not aware of your exact sorting logic.
|
0

Omitting the algorithms (bubble, quicksort, by inserting ...). There is possible of sorting in UI context.

Your json have: title | cost | unit | type

What type of sort You need? (title is string (can eg. sort alphabetically), then cost, unit & type are number (ascending + descending)

It's will be helpfull - when in future You provide only neccessary piece of code.


Here it's ellegant minimalistic function responsible for asc/desc sorting.

Firstly it's need to pass the props(which You wan't to sort) to values state.

function App() {
  const [ascValue, setAscValue] = useState(true);
  const [values, setValues] = useState([10, 5, 12, 1, 2, 900, 602]);

  function sortValues() {
    const compare = ascValue ? (a, b) => a - b : (a, b) => b - a;
    setValues([...values].sort(compare));
  }

  useEffect(() => {
    sortValues();
  }, [ascValue]);

  return (
    <div>
      <h3>{ascValue.toString()}</h3>
      <button onClick={() => setAscValue(!ascValue)}>Toggle Asc</button>
      {values.map(v => (
        <p key={v}>{v}</p>
      ))}
    </div>
  );
}

Here is sorting by cost for your object:

let text = [{
    "index": 1,
    "id": "5e3961face022d16a03b1de9_1023632_1004876",
    "costtable": [
        {
            "roomname": "Single",
            "room_id": "1023632_479490,1004876_385485",
            "family": [
                {
                    "title": "adult 1",
                    "cost": 3.7568000,
                    "unit": "10",
                    "type": "2"
                }
            ]
        }
    ]
},
{
    "index": 2,
    "id": "5e3961face022d16a03b1de9_1088496_1005362",
    "costtable": [
        {
            "roomname": "Double",
            "room_id": "1088496_447339,1005362_415279",
            "family": [
                {
                    "title": "adult 1",
                    "cost": 5.6868000,
                    "unit": "10",
                    "type": "2"
                }
            ]
        }
    ]
},
{
    "index": 3,
    "id": "5e3961face022d16a03b1de9_1141859_1005529",
    "costtable": [
        {
            "roomname": "Single",
            "room_id": "1141859_74888,1005529_870689",
            "family": [
                {
                    "title": "adult 1",
                    "cost": 5.9586000,
                    "unit": "10",
                    "type": "2"
                }
            ]
        }
    ]
}
]

const App = () =>{

    const usersWithName = Object.keys(text).map(function(key) {
        var user = text[key];
        return user.costtable[0].family[0].cost;
      });

    let costArray = usersWithName

    const [ascValue, setAscValue] = useState(true);
    const [values, setValues] = useState(costArray);


        function sortValues() {
            const compare = ascValue ? (a, b) => a - b : (a, b) => b - a;
            setValues([...values].sort(compare));
          }


        useEffect(() => {
            sortValues();
          }, [ascValue]);




        return (
        <div>
            <h3>{ascValue.toString()}</h3>
            <button onClick={() => setAscValue(!ascValue)}>Toggle Asc</button>
            {values.map(v => (
                <p key={v}>{v}</p>
            ))}
        </div>
        );
    }

export default App;

I don't have idea of performance in this case + if in your json are more costtable & family it should iterate by [i] iterator.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.