3

Hi Stack Overflow community!

I have the following test array:

let test = [{
    "searchQuery": "test",
    "resultsLoaded": -1,
    "offset": -1,
    "allResults": 10
}, {
    "metaData": {
        "type": "page-content",
        "image": true,
        "name": "lorem-ipsum",
        "rank": 10,
        "tags": ["website:lorem/ipsum"]
    },
    "componentData": {
        "header": "Lorem Ipsum",
        "path": "/content/asdf",
        "breadcrumbDouble": {
            "breadcrumbItem1": {
                "href": "lorem ipsum",
                "text": "lorem ipsum"
            },
            "breadcrumbItem2": {
                "href": "/content/asdf",
                "text": "Lorem Ipsum"
            }
        },
        "content": {
            "subheadline": "Lorem Ipsum",
            "img": {
                "alt": "",
                "imgSrc": "/content/dam/production/images/asdf.jpeg.imgTransformer/listPageItem/desktop/1511962617778/asdf.jpg"
            },
            "tags": [{
                "category": "lorem",
                "value": "ipsum"
            }]
        }
    }
}, {
    "metaData": {
        "type": "page-content",
        "image": true,
        "name": "lorem-ipsum",
        "rank": 50,
        "tags": ["website:lorem/ipsum"]
    },
    "componentData": {
        "header": "Lorem Ipsum",
        "path": "/content/asdf",
        "breadcrumbDouble": {
            "breadcrumbItem1": {
                "href": "lorem ipsum",
                "text": "lorem ipsum"
            },
            "breadcrumbItem2": {
                "href": "/content/asdf",
                "text": "Lorem Ipsum"
            }
        },
        "content": {
            "subheadline": "Lorem Ipsum",
            "img": {
                "alt": "",
                "imgSrc": "/content/dam/production/images/asdf.jpeg.imgTransformer/listPageItem/desktop/1511962617778/asdf.jpg"
            },
            "tags": [{
                "category": "lorem",
                "value": "ipsum"
            }]
        }
    }
}, {
    "metaData": {
        "type": "page-content",
        "image": true,
        "name": "lorem-ipsum",
        "rank": 30,
        "tags": ["website:lorem/ipsum"]
    },
    "componentData": {
        "header": "Lorem Ipsum",
        "path": "/content/asdf",
        "breadcrumbDouble": {
            "breadcrumbItem1": {
                "href": "lorem ipsum",
                "text": "lorem ipsum"
            },
            "breadcrumbItem2": {
                "href": "/content/asdf",
                "text": "Lorem Ipsum"
            }
        },
        "content": {
            "subheadline": "Lorem Ipsum",
            "img": {
                "alt": "",
                "imgSrc": "/content/dam/production/images/asdf.jpeg.imgTransformer/listPageItem/desktop/1511962617778/asdf.jpg"
            },
            "tags": [{
                "category": "lorem",
                "value": "ipsum"
            }]
        }
    }
}];

What I want to achive now is to sort the objects by metaData.rank from highest to lowest.

I wanted to use lodash's orderBy() like this:

let result = orderBy(test, function(e) {
    let array = parseInt(e.metaData.rank);
    return array;
}, ['desc']);

But I get the following error:

TypeError: Cannot read property 'rank' of undefined

console.log(e) in my orderBy function shows me this:

{
    searchQuery: 'test',
    resultsLoaded: -1,
    offset: -1,
    allResults: 10
}

Any quick suggestions to fix this?

I know that the first object is causing the problem because of the different structure. So I need to work around it!

3
  • 1
    what is with the first entry? should it stay on top? Commented Nov 29, 2017 at 15:46
  • @NinaScholz In the best case, it should stay on top. Commented Nov 29, 2017 at 15:52
  • 1
    @mrks Is the different object always in the first position? Could be more of it in the same array? Commented Nov 29, 2017 at 16:01

3 Answers 3

2

You could move the items without metaData property to top and sort the rest by rank.

var array = [{ searchQuery: "test", resultsLoaded: -1, offset: -1, allResults: 10 }, { metaData: { type: "page-content", image: true, name: "lorem-ipsum", rank: 10, tags: ["website:lorem/ipsum"] }, componentData: { header: "Lorem Ipsum", path: "/content/asdf", breadcrumbDouble: { breadcrumbItem1: { href: "lorem ipsum", text: "lorem ipsum" }, breadcrumbItem2: { href: "/content/asdf", text: "Lorem Ipsum" } }, content: { subheadline: "Lorem Ipsum", img: { alt: "", imgSrc: "/content/dam/production/images/asdf.jpeg.imgTransformer/listPageItem/desktop/1511962617778/asdf.jpg" }, tags: [{ category: "lorem", value: "ipsum" }] } } }, { metaData: { type: "page-content", image: true, name: "lorem-ipsum", rank: 50, tags: ["website:lorem/ipsum"] }, componentData: { header: "Lorem Ipsum", path: "/content/asdf", breadcrumbDouble: { breadcrumbItem1: { href: "lorem ipsum", text: "lorem ipsum" }, breadcrumbItem2: { href: "/content/asdf", text: "Lorem Ipsum" } }, content: { subheadline: "Lorem Ipsum", img: { alt: "", imgSrc: "/content/dam/production/images/asdf.jpeg.imgTransformer/listPageItem/desktop/1511962617778/asdf.jpg" }, tags: [{ category: "lorem", value: "ipsum" }] } } }, { metaData: { type: "page-content", image: true, name: "lorem-ipsum", rank: 30, tags: ["website:lorem/ipsum"] }, componentData: { header: "Lorem Ipsum", path: "/content/asdf", breadcrumbDouble: { breadcrumbItem1: { href: "lorem ipsum", text: "lorem ipsum" }, breadcrumbItem2: { href: "/content/asdf", text: "Lorem Ipsum" } }, content: { subheadline: "Lorem Ipsum", img: { alt: "", imgSrc: "/content/dam/production/images/asdf.jpeg.imgTransformer/listPageItem/desktop/1511962617778/asdf.jpg" }, tags: [{ category: "lorem", value: "ipsum" }] } } }];

array.sort(function (a, b) {
    return ('metaData' in a) - ('metaData' in b) || b.metaData.rank - a.metaData.rank;
});

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

Sign up to request clarification or add additional context in comments.

2 Comments

Do you have an idea how to adapt your solution to check first for the rank and if, for example, two objects have the same rank to order them by alphabet componentData.header?
you could chain the next order criterium by using another logicla or at the end like ... || a.componentData.header > b.componentData.header || -(a.componentData.header < b.componentData.header) for a sorting by alphabet (it works even for numbers as well).
1

The first object in the array test is causing that problem. It doesn't have the same structure as the others. If e was that first object, then e.metaData is undefined.

I suggest you shift that first object, sort the array, then unshift it back to the sorted array:

let test = [...];

let first = test.shift();                                  // remove the first object from the array and store it in 'first'
test.sort((a, b) => b.metaData.rank - a.metaData.rank);    // sort the array (you can use orderBy here if you want)
test.unshift(first);                                       // unshift the first object (return it back to the first index of the array)

Note: The solution I suggested assumes there is only one different object and that this object always at the index 0.

2 Comments

This doesn't seem extendable. What if that element is at a different index? Rest two answers seem to be working with all scenarios.
@31piy I don't think that object could be at another position (it is a header object that describes the others). I'll ask OP for more clarification.
1

instead e.metaData.rank use:

_.get(e, ['metaData', 'rank'], /*value if rank field is not exist*/ -1);

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.