【问题标题】:Sort objects in array by key with lodash使用 lodash 按键对数组中的对象进行排序
【发布时间】:2018-05-13 09:12:01
【问题描述】:

你好 Stack Overflow 社区!

我有以下测试数组:

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"
            }]
        }
    }
}];

我现在想要实现的是按metaData.rank从高到低对对象进行排序。

我想像这样使用 lodash 的 orderBy()

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

但我收到以下错误:

TypeError: 无法读取未定义的属性“等级”

console.log(e) 在我的orderBy 函数中向我展示了这个:

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

有解决此问题的快速建议吗?

我知道由于结构不同,第一个对象导致了问题。所以我需要解决它!

【问题讨论】:

  • 第一个条目是什么?它应该保持在首位吗?
  • @NinaScholz 在最好的情况下,它应该保持在顶部。
  • @mrks 不同的对象总是在第一位吗?在同一个数组中可以有更多吗?

标签: javascript arrays sorting object lodash


【解决方案1】:

您可以将没有metaData 属性的项目移到顶部,然后按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; }

【讨论】:

  • 您知道如何调整您的解决方案以首先检查排名,例如,如果两个对象具有相同的排名以按字母表componentData.header 对它们进行排序?
  • 您可以通过使用另一个逻辑或在末尾(如... || a.componentData.header > b.componentData.header || -(a.componentData.header < b.componentData.header))链接下一个顺序标准以按字母排序(它甚至适用于数字)。
【解决方案2】:

数组test 中的第一个对象导致了该问题。它的结构与其他结构不同。如果e 是第一个对象,那么e.metaData 就是undefined

我建议你shift第一个对象,sort数组,然后unshift返回排序数组:

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)

注意:我建议的解决方案假定只有一个不同的对象,并且该对象始终位于索引 0

【讨论】:

  • 这似乎不可扩展。如果该元素位于不同的索引处怎么办?其余两个答案似乎适用于所有情况。
  • @31piy 我不认为该对象可能位于另一个位置(它是描述其他对象的标题对象)。我会要求 OP 进行更多说明。
【解决方案3】:

改为e.metaData.rank 使用:

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

【讨论】:

    猜你喜欢
    • 2017-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-11
    • 1970-01-01
    相关资源
    最近更新 更多