【问题标题】:Not able to sort array of objects无法对对象数组进行排序
【发布时间】:2013-09-06 16:09:57
【问题描述】:

我有以下数组:

[
    {
        "BestCoupon": 1,
        "Saving": "100",
        "Successful": 1,
        "couponCode": "CRIC100",
        "description": "Get Rs. 100 Discount on purchase of Rs. 599 & above. Products include Eyeglasses & Sunglasses and more. Choose",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    },
    {
        "BestCoupon": 0,
        "Saving": "NOT APPLICABLE :Coupon code \"CRIC200\" is not valid.",
        "Successful": 0,
        "couponCode": "CRIC200",
        "description": "Get Rs. 200 Discount on purchase of Rs. 999 & above. Products include Eyeglasses & Sunglasses and more. Choose",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    },
    {
        "BestCoupon": 0,
        "Saving": "NOT APPLICABLE : Coupon code \"CRIC300\" is not valid.",
        "Successful": 0,
        "couponCode": "CRIC300",
        "description": "Get Rs. 300 Discount on purchase of Rs. 1199 & above. Products include Eyeglasses, Sunglasses & Contact Lenses",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    },
    {
        "BestCoupon": 0,
        "Saving": "NOT APPLICABLE: Coupon code \"JJPREMIUM\" is not valid.",
        "Successful": 0,
        "couponCode": "JJPREMIUM",
        "description": "Get Rs 600 Discount on John Jacobs Eyeglasses. Products include Eyeglasses. Choose from brand like John",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    },
    {
        "BestCoupon": 0,
        "Saving": "NOT APPLICABLE: Coupon code \"LENS20130303\" is not valid.",
        "Successful": 0,
        "couponCode": "LENS20130303",
        "description": "Get Rs. 500 Discount on purchase of Rs. 1000. Products include Eyeglasses, Sunglasses & Contact Lenses and",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    },
    {
        "BestCoupon": 0,
        "Saving": "179.8",
        "Successful": 1,
        "couponCode": "LKEND20",
        "description": "Get 20% Discount on Eyeglasses. Minimum Purchase Rs. 499. Products include Eyeglasses. Choose from brandslike",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    },
    {
        "BestCoupon": 0,
        "Saving": "224.75",
        "Successful": 1,
        "couponCode": "LKEND25",
        "description": "Flat 25% off on purchase of Rs 799 & above",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    },
    {
        "BestCoupon": 0,
        "Saving": "NOT APPLICABLE : Coupon code \"LKEND30\" is not valid.",
        "Successful": 0,
        "couponCode": "LKEND30",
        "description": "Get 30% Discount on purchase of Rs 1299 & above. Products include Eyeglasses, Sunglasses & Contact Lenses and",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    },
    {
        "BestCoupon": 0,
        "Saving": "NOT APPLICABLE : Coupon code \"LKEND35\" is not valid.",
        "Successful": 0,
        "couponCode": "LKEND35",
        "description": "Get 35% Discount on purchase of Rs 1499 & above. Products include Eyeglasses, Sunglasses & Contact Lenses and",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    },
    {
        "BestCoupon": 0,
        "Saving": "100",
        "Successful": 1,
        "couponCode": "OMGABV600",
        "description": "Get Rs. 100 Discounton order of Rs. 600 & Above. Products include Eyeglasses, Sunglasses & Contact Lenses and",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    },
    {
        "BestCoupon": 0,
        "Saving": "NOT APPLICABLE : Coupon code \"POWERSUN20\" isnot valid.",
        "Successful": 0,
        "couponCode": "POWERSUN20",
        "description": "Get 20% OFFon Power Sunglasses. Select from a vast collection.",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    },
    {
        "BestCoupon": 0,
        "Saving": "179.8",
        "Successful": 1,
        "couponCode": "WEEKEND20",
        "description": "Flat 20% OFF on purchase of Rs 499 & above - NA on Premium Brands & Contact Lenses",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    }
]

我想按“储蓄”的降序对其进行排序。我正在使用以下代码

couponObj.sort(function (a, b) {
      if (a[0].Saving == b[0].Saving)
         return 0;
      if (a[0].Saving > b[0].Saving)
         return -1;
      if (a[0].Saving < b[0].Saving)
         return 1;
});

它给了我以下结果:

[
    {
        "BestCoupon": 0,
        "Saving": "NOT APPLICABLE : Coupon code \"POWERSUN20\" is not valid.",
        "Successful": 0,
        "couponCode": "POWERSUN20",
        "description": "Get 20% OFF on Power Sunglasses. Select from a vast collection.",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    },
    {
        "BestCoupon": 0,
        "Saving": "NOT APPLICABLE : Coupon code \"LKEND35\" is not valid.",
        "Successful": 0,
        "couponCode": "LKEND35",
        "description": "Get 35% Discount on purchase of Rs 1499 & above. Products include Eyeglasses, Sunglasses & Contact Lenses and",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    },
    {
        "BestCoupon": 0,
        "Saving": "NOT APPLICABLE : Coupon code \"LKEND30\" is not valid.",
        "Successful": 0,
        "couponCode": "LKEND30",
        "description": "Get 30% Discount on purchase of Rs 1299 & above. Products include Eyeglasses, Sunglasses & Contact Lenses and",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    },
    {
        "BestCoupon": 0,
        "Saving": "NOT APPLICABLE : Coupon code \"LENS20130303\" is not valid.",
        "Successful": 0,
        "couponCode": "LENS20130303",
        "description": "Get Rs. 500 Discount on purchase of Rs. 1000. Products include Eyeglasses, Sunglasses & Contact Lenses and",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    },
    {
        "BestCoupon": 0,
        "Saving": "NOT APPLICABLE : Coupon code \"JJPREMIUM\" is not valid.",
        "Successful": 0,
        "couponCode": "JJPREMIUM",
        "description": "Get Rs 600 Discount on John Jacobs Eyeglasses. Products include Eyeglasses. Choose from brand like John",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    },
    {
        "BestCoupon": 0,
        "Saving": "NOT APPLICABLE : Coupon code \"CRIC300\" is not valid.",
        "Successful": 0,
        "couponCode": "CRIC300",
        "description": "Get Rs. 300 Discount on purchase of Rs. 1199 & above. Products include Eyeglasses, Sunglasses & Contact Lenses",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    },
    {
        "BestCoupon": 0,
        "Saving": "NOT APPLICABLE : Coupon code \"CRIC200\" is not valid.",
        "Successful": 0,
        "couponCode": "CRIC200",
        "description": "Get Rs. 200 Discount on purchase of Rs. 999 &above. Products include Eyeglasses & Sunglasses and more. Choose",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    },
    {
        "BestCoupon": 0,
        "Saving": "224.75",
        "Successful": 1,
        "couponCode": "LKEND25",
        "description": "Flat 25% off on purchase of Rs 799 & above",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    },
    {
        "BestCoupon": 0,
        "Saving": "179.8",
        "Successful": 1,
        "couponCode": "LKEND20",
        "description": "Get 20% Discount on Eyeglasses. Minimum Purchase Rs. 499. Products include Eyeglasses. Choose from brands like",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    },
    {
        "BestCoupon": 0,
        "Saving": "179.8",
        "Successful": 1,
        "couponCode": "WEEKEND20",
        "description": "Flat 20%OFF on purchase of Rs 499 & above - NA on Premium Brands & Contact Lenses",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    },
    {
        "BestCoupon": 0,
        "Saving": "100",
        "Successful": 1,
        "couponCode": "CRIC100",
        "description": "Get Rs. 100 Discount on purchase of Rs. 599 & above. Products include Eyeglasses & Sunglasses and more. Choose",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    },
    {
        "BestCoupon": 0,
        "Saving": "100",
        "Successful": 1,
        "couponCode": "OMGABV600",
        "description": "Get Rs. 100 Discount on order of Rs. 600 & Above. Products include Eyeglasses, Sunglasses & Contact Lenses and",
        "domain": "www.lenskart.com",
        "url": "http://www.lenskart.com/checkout/cart/"
    }
]

基本上,它在保存为字符串的数组项的顶部进行排序。我希望它们在底部。

【问题讨论】:

  • 这是一个对象数组,不是 Json 字符串
  • 为什么使用a[0].Saving而不是a.Saving
  • 我已编辑您的问题以删除对 JSON 的引用,因为它似乎与它没有任何关系。如果我错了,请随时纠正。
  • 一个小建议:有一个名为 SavingText 的附加键并将“不适用”文本移动到那里并将 Saving 设置为 0。
  • 如果你对他们在说什么感到困惑,JSON 是一种将数据放入字符串中以进行传输的方式,而对象是 JavaScript 中实际数据结构的使用方式

标签: javascript sorting


【解决方案1】:

当比较器函数提供给Array.prototype.sort 时,它被赋予参数ab,它们是原始数组的元素,而不是数组本身。

因此,在这种特殊情况下,您需要删除 [0]。例如,而不是:

if (a[0].Saving == b[0].Saving) { ...

尝试:

if (a.Saving === b.Saving) { ...
           // ^-- also, it's best to use strict comparison

【讨论】:

    【解决方案2】:

    看起来您正在尝试访问似乎不存在的对象的属性0;并在纠正它的同时,更容易看到发生了什么。

    couponObj.sort(function (a, b) {
        a = +a.Saving, b = +b.Saving; // cast Number
        // special cases
        if (a !== a || b !== b)           // If there is a NaN
            return (a !== a) - (b !== b); // move it to the end
        // classic descending sort
        return b - a;
    });
    

    【讨论】:

    • +1 为什么不是经典的return b - a? JS有什么不同吗?
    • 我问是因为人们永远无法知道像 JS 这样的弱类型语言......也许有一些隐藏的东西(比如你使用 ===,但至少我知道)
    • 考虑到他有各种 NaN 值(“文本”值),也许将它们作为特殊情况处理会更好:-)
    • @xanatos 我们知道这个例子很好,因为我已经做了演员表。您可能需要考虑如果没有演员表是否可以并且您期望不同的类型
    • NaN 不会被移动,真的。让我解决这个问题。
    【解决方案3】:

    正如其他人所建议的那样,但需要注意的是:您有各种 Saving 是文本而不是描述...

    couponObj.sort(function (a, b) {
        a = parseFloat(a.Saving); // cast to number
        b = parseFloat(b.Saving); // cast to number
    
        if (isNaN(a)) return isNaN(b) ? 0 : 1;
        if (isNaN(b)) return -1;
    
        return b - a; // descending order
    });
    

    当您尝试使用+ 将非数字转换为数字时,返回的数字是NaN(一个不能很好排序的特殊值)。为此各种if (isNaN())

    请注意,在初始版本中,我使用+a.Saving 将字符串转换为数字,但我已将其更改为parseFloatnull 有细微的差别:+null === 0,而parseFloat(null) === NaN(那我可以处理)。

    【讨论】:

    • 希望ab 不是null ;)
    • @Oleg +null 为 0...mmmmh
    • +null.Saving -> "TypeError: Cannot read property 'Saving' of null" 因为在尝试“强制转换”为数字之前将读取该属性。
    • @Oleg Ah... 不,我在想a.Saving 可能是nullundefined
    • 看起来漂亮整洁。示例 JSON 没有任何 null 条目,所以我认为我们不需要担心,除非它得到 OP 的说明
    【解决方案4】:

    使用 parseFloat 方法将字符串转换为浮点数:

    couponObj.sort(function (a, b) {
      if(a && b) {
        var af = parseFloat(a.Saving);
        var bf = parseFloat(b.Saving);
        if(isNan(af)) return 1;
        if(isNan(bf)) return -1;
        return bf-af;
      }
      return 0; // ignore null entries
    }
    

    【讨论】:

      最近更新 更多