0

I need to sort an array of nested objects. I wrote the following code but for some reasons it places the first element always in the returning array even if it should not.

orderedArray = () => {
    let sortedArray = products
    if(this.state.interests.design && this.state.interests.code && this.state.interests.business)
        sortedArray.sort((a,b)=> (b.scores.quality-a.scores.quality))
    else if(this.state.interests.design && this.state.interests.code)
        sortedArray.sort((a,b) => (b.scores.quality*b.scores.relevancy.code*b.scores.relevancy.design/2)-(a.scores.quality*a.scores.relevancy.code*a.scores.relevancy.design/2))
    else if(this.state.interests.design && this.state.interests.business)
        sortedArray.sort((a,b) => (b.scores.quality*b.scores.relevancy.business*b.scores.relevancy.design/2)-(a.scores.quality*a.scores.relevancy.business*a.scores.relevancy.design/2))
    else if(this.state.interests.business && this.state.interests.code)
        sortedArray.sort((a,b) => (b.scores.quality*b.scores.relevancy.business*b.scores.relevancy.code/2)-(a.scores.quality*a.scores.relevancy.business*a.scores.relevancy.code/2))
    else if(this.state.interests.business)
        sortedArray.sort((a,b)=> (b.scores.quality*b.scores.relevancy.business-a.scores.quality*a.scores.relevancy.busines))
    else if(this.state.interests.code)
        sortedArray.sort((a,b)=> (b.scores.quality*b.scores.relevancy.code-a.scores.quality*a.scores.relevancy.code))
    else if(this.state.interests.design)
        sortedArray.sort((a,b)=> (b.scores.quality*b.scores.relevancy.design-a.scores.quality*a.scores.relevancy.design))
    console.log(JSON.stringify(sortedArray))
    return sortedArray
}

The idea is that if they selected design, business and code then the resulting array should be sorted by quality, otherwise my a mix of quality and the selected variables. Here is the data:

[
    {
        "name":"dasd",
        "scores": {
            "quality": 8,
            "relevancy": {
                "design": 3,
                "code": 9,
                "business": 5
            }
        },
        {...}
    }
    {...}
]

Whereas this.state is:

    this.state = {
        minutes: int,
        interests: {
                business: bool,
                code: bool,
                design: bool
        }
    }
5
  • 3
    please add the data as well in literal notation. Commented May 25, 2017 at 19:03
  • 2
    What do you mean by "places the first element always in the returning array"? sort doesn't place or remove anything. Commented May 25, 2017 at 19:06
  • the sortedArray has the same first element than at the beginning of the operation Commented May 25, 2017 at 19:07
  • how-to-sort-an-array-of-objects-by-multiple-fields ? Even if it was not a duplicate, I think it would help to take a look. Commented May 25, 2017 at 19:08
  • @NinaScholz added Commented May 25, 2017 at 19:12

1 Answer 1

1

Using a formula does not work to sort an array on multiple properties.

Given an array of "student" objects with structure like {name:'Alice', age:8, grades:{math:12, gym:14}}, the following does not work:

// This does not sort by math then gym, it sorts by the result of their products, which is meaningless
students.sort((a,b) => (a.grades.math*a.grades.gym - b.grades.math*b.grades.gym))

As you can see in this Q/A, it's difficult to implement in JS, but there are libraries to help make this much straightforward, like underscore or lodash.

With lodash you can do this:

// This sorts by math score, then gym score
_.sortBy(students, [s => s.grades.math, s => s.grades.gym])

Now applying to your problem, without giving a complete solution, here is a hint:

var data = [...];
var propertiesToSortBy = [ o => o.scores.quality ];
// Your rules below
if (...) {
    propertiesToSortBy = [ o => o.scores.quality, o => o.scores.relevancy.business ];
}
else if (...) {
    propertiesToSortBy = [ o => o.scores.relevancy.design, o => o.scores.relevancy.business ];
}
else ...
// Finally, sort
_.sortBy(data, propertiesToSortBy);
Sign up to request clarification or add additional context in comments.

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.