【问题标题】:How to sort a nested array based on value with lodash?如何使用 lodash 根据值对嵌套数组进行排序?
【发布时间】:2019-07-26 10:44:53
【问题描述】:

我正在学习如何使用 lodash 库,但遇到了一个我认为我不知道如何解决的问题。我想用 lodash 对一个看起来像这样的嵌套数组进行排序:

"results": [
  {
        "id": "12345",
        "name": "toy123",
        "date_created": "2017-08-29T16:10:37Z",
        "date_last_modified": "2019-01-29T17:19:36Z",
        "prices": [
            {
                "currency": "USD",
                "amount": "100.00"
            },
            {
                "currency": "EUR",
                "amount": "88.23"
            },
        ]
    },
    {
        "id": "54321",
        "name": "toy321",
        "date_created": "2017-08-29T16:10:37Z",
        "date_last_modified": "2019-01-29T17:19:36Z",
        "prices": [
            {
                "currency": "USD",
                "amount": "80.00"
            },
            {
                "currency": "EUR",
                "amount": "70.58"
            },
        ]
    },
]

我想根据嵌套在给定数组中的prices 数组对数组进行排序。排序将考虑prices.currencyprices.amount 并产生如下输出,其中给定数组基于USDamount 升序排序。我遇到的另一个问题是prices.amount 是一个字符串,而不是一个数字。

[
    {
        "id": "54321",
        "name": "toy321",
        "date_created": "2017-08-29T16:10:37Z",
        "date_last_modified": "2019-01-29T17:19:36Z",
        "prices": [
            {
                "currency": "USD",
                "amount": "80.00"
            },
            {
                "currency": "EUR",
                "amount": "70.58"
            },
        ]
  },
  {
        "id": "12345",
        "name": "toy123",
        "date_created": "2017-08-29T16:10:37Z",
        "date_last_modified": "2019-01-29T17:19:36Z",
        "prices": [
            {
                "currency": "USD",
                "amount": "100.00"
            },
            {
                "currency": "EUR",
                "amount": "88.23"
            },
        ]
    },
]

非常感谢您的好意,当然还有您的时间。

【问题讨论】:

  • 您能否详细说明排序部分。按美元和金额排序是什么意思?
  • price.amount 不是问题,因为您将获得第一个 parseInt 然后比较的灵活性
  • @binariedMe 这意味着数组是根据金额排序的,货币为美元。
  • 嗯,其他人已经按照你的要求回答了。我认为它们应该可以正常工作。

标签: javascript arrays sorting filter lodash


【解决方案1】:

_.sortBy() 方法不支持自定义比较器,您应该改用Array.prototype.sort()。你也不需要解析prices.amountString.prototype.localeCompare()可以帮你做比较,它支持带数值的字符串。

综合起来,您的实现可能如下所示:

results.sort((a, b) => {
    const priceA = _.find(a.prices, { currency: 'USD' });
    const priceB = _.find(b.prices, { currency: 'USD' });
    return priceA.amount.localeCompare(priceB.amount, undefined, { numeric: true });
});

【讨论】:

  • 这将为数组中的每个项目构造一个新的比较函数,看看我下面的解决方案,看看如何缓存比较函数以获得更好的性能。
  • 在我看来,您的解决方案非常复杂且难以理解,这是一种非常迂回的方法来做一些非常简单的事情。您的解决方案还会再迭代两次结果并创建两个新数组。它在哪些方面表现更好?你有任何基准吗?
  • 您确定要查看我的解决方案吗?
  • 对不起,我看到了“缓存”,看到了另一个答案是“缓存”。我不知道Intl.Collator 感谢分享!
【解决方案2】:

不需要像 loadash 这样的外部库。

const arr = [
  {
        "id": "12345",
        "name": "toy123",
        "date_created": "2017-08-29T16:10:37Z",
        "date_last_modified": "2019-01-29T17:19:36Z",
        "prices": [
            {
                "currency": "USD",
                "amount": "100.00"
            },
            {
                "currency": "EUR",
                "amount": "88.23"
            },
        ]
    },
    {
        "id": "54321",
        "name": "toy321",
        "date_created": "2017-08-29T16:10:37Z",
        "date_last_modified": "2019-01-29T17:19:36Z",
        "prices": [
            {
                "currency": "USD",
                "amount": "80.00"
            },
            {
                "currency": "EUR",
                "amount": "70.58"
            },
        ]
    },
];

const naturalSort = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }).compare;

arr.sort((a,b) => naturalSort(a.prices.find(p => p.currency === 'USD').amount, b.prices.find(p => p.currency === 'USD').amount));

console.log(arr);

【讨论】:

  • 您使用sensitivity: 'base' 的任何特殊原因?
  • 这个例子不是真的,它可能来自这个例子中的复制和粘贴。当我创建一个不区分大小写的国际整理器时,我总是使用它。
【解决方案3】:

并通过缓存价格查找进行优化,否则将对每个项目执行多次..

const results = [
  {
    "id": "12345",
    "name": "toy123",
    "date_created": "2017-08-29T16:10:37Z",
    "date_last_modified": "2019-01-29T17:19:36Z",
    "prices": [
      { "currency": "USD", "amount": "100.00" },
      { "currency": "EUR", "amount": "88.23" },
    ]
  },
  {
    "id": "54321",
    "name": "toy321",
    "date_created": "2017-08-29T16:10:37Z",
    "date_last_modified": "2019-01-29T17:19:36Z",
    "prices": [
      { "currency": "USD", "amount": "80.00" },
      { "currency": "EUR", "amount": "70.58" },
    ]
  },
];

function sortResults(results, curr) {
  return results
    .map(result => ([result, result.prices.find(price => price.currency === curr).amount - 0]))
    .sort((a, b) => a[1] - b[1])
    .map(res => res[0]);
}

console.log(sortResults(results, "USD").map(res => res.name));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-19
    • 1970-01-01
    • 2018-11-30
    • 1970-01-01
    相关资源
    最近更新 更多