【问题标题】:Javascript custom sorting an array of objects by year with 'pre year'Javascript自定义使用“前年”按年份对对象数组进行排序
【发布时间】:2017-01-06 19:11:54
【问题描述】:

所以我有一个对象数组,例如:

var a = {user: [
 {year:'1950',name:'Joe'},
 {year:'19XX',name:'Chris'},
 {year:'1980',name:'Bob'},
 {year:'1955',name:'Jan'}
]}

我使用这些数据来模板化包含年份和名称的简单元素。 我还可以通过 select 元素选择对这些数据进行排序,然后使用 sorted 按排序顺序再次对其进行模板化。 (bob,chris,jan,joe) 或年份。 但我的问题从年份开始。

我需要继续使用一个简单的插件 jsonQ (http://ignitersworld.com/lab/jsonQ.html) 要编辑和排序数据,并且需要使年份的数据实际上与 desc 或 asc 略有不同。

第一次我需要编辑各个部分的数据,比如年份(19XX 应该变成“Pre 1950”):

//inside ajax success function
var dataObj = jsonQ(data);

dataObj.find('year').value(function (data){
   if (data == '19XX') {
       return 'pre 1953'
   } else {
       return data;
   }
});

现在我将有一个需要排序的最终产品数据集。

var orderedData = dataObj.sort('year', {'order' : 'ASC'});  

但这给了我数据:

{
 user: [
  {year:'1950',name:'Joe'},
  {year:'1955',name:'Jan'},     
  {year:'1980',name:'Bob'},
  {year:'Pre 1950',name:'Chris'}
 ]
}

我需要的是要返回的数据:

{
 user: [
  {year:'Pre 1950',name:'Chris'},
  {year:'1950',name:'Joe'},
  {year:'1955',name:'Jan'},     
  {year:'1980',name:'Bob'}
 ]
}

有什么建议吗?

【问题讨论】:

  • 您需要定义自己的比较函数。实际上 P 在字典上比任何数字都大。

标签: javascript arrays json sorting


【解决方案1】:

好吧,您可以实现自己的排序标准,并将其传递给Array.sort()

此标准采用返回数字的function(a, b) 的形式:

  • 否定如果a在排序列表中应该排在b之前
  • 如果ab 基本相等
  • 积极 如果a 应该追随b

这可能看起来很随意,但可以这样想:在将数字从小到大排序的简单情况下,函数返回a - b。所以,f(a, b)a - ba - b < 0 表示 a < b

回到你的情况。让我们实现一个标准函数,将年份从小到大排序,将 Pre 1950 放在顶部:

function byYear(a, b) {
  if (a === "Pre 1950") return -1 // a goes before
  if (b === "Pre 1950") return 1  // b goes before

  return parseInt(a) - parseInt(b) // lesser goes before
})

在浏览器控制台中试一试:

> ["1980", "1970", "Pre 1950"].sort(byYear)
["Pre 1950", "1970", "1980"]

鉴于您正在对对象进行排序,您需要调整上面的标准函数以使用 a.yearb.year

【讨论】:

  • if (a === "Pre 1950") return -1; 部分不是必需的。
  • 我想你说得有道理。 +1以获得详细答案。干得好。
  • @slezica - 是的,+1 这是理解这种操作的一个很好的答案。我特别被这个插件卡住了。
【解决方案2】:

您可以分三步对数组进行排序

  • 排序优先年份,如19XX
  • 按年份排序,无优先级
  • 按名称排序。

var a = { user: [{ year: '1950', name: 'Joe' }, { year: '19XX', name: 'Chris' }, { year: '1980', name: 'Bob' }, { year: '1955', name: 'Jan' }] };

a.user.sort(function (a, b) {
    var order = { '19XX': -1 };
    return (order[a.year] || 0) - (order[b.year] || 0) || a.year - b.year || a.name.localeCompare(b.name);
});

console.log(a);

【讨论】:

    【解决方案3】:

    我刚刚在发布后不久在使用插件时找到了解决方案。 (这是我想要的,抱歉,我应该更详细地说明)。

    我的问题在于传递给插件的sort()method 的选项。 不容易找到,因为文档不是 100。

    var orderedData = dataObj.sort('year', {
      'order' : 'ASC',
      logic: function(val){
         return (val == 'pre 1950') ? '1911' : val;
      }
    });
    

    这实际上是用 1911 替换 'pre 1950',只是为了排序。

    【讨论】:

    • 你可以跳过围绕条件的paranteses。
    • @NinaScholz - 你是对的.. 旧习惯很难改掉 :)
    猜你喜欢
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2019-02-23
    • 1970-01-01
    • 1970-01-01
    • 2021-08-08
    • 2021-01-20
    • 2020-08-15
    相关资源
    最近更新 更多