为什么我的 javascript 排序函数没有生成正确的顺序?

Why is my javascript sort function not producing the correct order?

我有一个函数可以根据数据属性中声明的结束日期对课程 (div) 进行排序。 类 的整个列表排序正确,只有一个除外。我不明白为什么它没有正确排序。 3 月 24 日是排序列表中的第一个。

我猜它只是在查看“24”中的“2”,但如果是这种情况,我不确定如何解决这个问题。

HTML

 <button onClick="courseSort()">SORT</button>

    <div id="course-container" class="row pb-5 pt-5">
        <div class="class-item col-12 col-md-6 pb-4" data-class-start="1/1/2022" data-class-end="5/28/2022">
            <h5>May 28</h5>
        </div>
        <div class="class-item col-12 col-md-6 pb-4" data-class-start="2/8/2022" data-class-end="3/9/2022">
            <h5>Mar 9</h5>
        </div>
        <div class="class-item col-12 col-md-6 pb-4" data-class-start="1/1/2022" data-class-end="3/5/2022">
            <h5>Mar 5</h5>
        </div>
        <div class="class-item col-12 col-md-6 pb-4" data-class-start="1/1/2022" data-class-end="4/1/2022">
            <h5>Apr 1</h5>
        </div>
        <div class="class-item col-12 col-md-6 pb-4" data-class-start="2/19/2022" data-class-end="3/8/2022">
            <h5>Mar 8</h5>
        </div>
        <div class="class-item col-12 col-md-6 pb-4" data-class-start="2/19/2022" data-class-end="3/24/2022">
            <h5>Mar 24</h5>
        </div>
        <div class="class-item col-12 col-md-6 pb-4" data-class-start="1/1/2022" data-class-end="4/23/2022">
            <h5>Apr 23</h5> 
        </div>
        <div class="class-item col-12 col-md-6 pb-4" data-class-start="1/1/2022" data-class-end="4/30/2022">
            <h5>Apr 30</h5>
        </div>
    </div>

JS

function sorter(a, b) {
    if (a.dataset.classEnd < b.dataset.classEnd)
        return -1;
    if (a.dataset.classEnd > b.dataset.classEnd)
        return 1;
    return 0;
}
  
// Function to sort Data
function courseSort() {
    var course = document.querySelectorAll("[data-class-end]");
    var courseArray = Array.from(course);
    let sorted = courseArray.sort(sorter);
    sorted.forEach(e =>
        document.querySelector("#course-container").appendChild(e));
}

谢谢

检查功能sorter(a, b)。例如,当您访问 a.dataset.classEnd 时,它是一个字符串,而不是日期。你可能想做这样的事情:

function sorter(a, b) {
  const [aDate, bDate] = [new Date(a.dataset.classEnd), new Date(b.dataset.classEnd)];
  if (aDate < bDate) return -1;
  if (aDate > bDate) return 1;
  return 0;
}

此外,您可以像 one-liner 那样简单地执行此操作,而不是单独的函数:

let sorted = courseArray.sort((a, b) => new Date(a.dataset.classEnd) - new Date(b.dataset.classEnd));

I am guessing it is only looking at the "2" in "24" but I am not sure how to get around this, if it is the case.

是的,这正是您比较字符串时发生的情况。

编辑:正如 Sebastian Simon 在评论中所建议的那样,您可能希望更改日期格式以允许排序而无需真正需要将变量转换为日期。

正如评论中已经提到的,日期的真实值可以从 Date 对象中导出。在下面的示例中,函数 courseArray(nodeList) 将:

  • 通过.map()将NodeList转换为数组运行
    [...nodeList].map(d => {...
    // [...nodeList] is the same as Array.from(nodeList)
    
  • data-class-end中提取值并将其转换为ISO格式
    let mmddyyyy = d.dataset.classEnd;
    let yyyymmdd = mmddyyyy.split('/');
    let yyyy = yyyymmdd.pop();
    yyyymmdd.unshift(yyyy);
    let ISO = yyyymmdd.join('-');
    // from mm/dd/yyyy to yyyy-mm-dd
    
  • 然后它被转换为 milli-seconds 自 1-1-1970 到 ISO 日期的数字 - 然后它被添加为 data-order 到 div 然后 div 根据 data-order 值重新排序。
      let ms = Date.parse(ISO);
      d.dataset.order = ms;
      return d;
    }).sort((a, b) => a.dataset.order - b.dataset.order);
    

此外,删除了内联事件处理程序并添加了一个事件 属性 事件处理程序。看看为什么 inline event handlers are garbage.

const courseArray = nodeList => {
  return [...nodeList].map(d => {
    let mmddyyyy = d.dataset.classEnd;
    let yyyymmdd = mmddyyyy.split('/');
    let yyyy = yyyymmdd.pop();
    yyyymmdd.unshift(yyyy);
    let ISO = yyyymmdd.join('-');
    let ms = Date.parse(ISO);
    d.dataset.order = ms;
    return d;
  }).sort((a, b) => a.dataset.order - b.dataset.order);
};

function courseSort() {
  const course = document.querySelectorAll(".class-item");

  let sorted = courseArray(course);
  sorted.forEach(e =>
    document.querySelector("#course-container").appendChild(e));
};

document.querySelector('button').onclick = courseSort;
<button>SORT</button>

<div id="course-container" class="row pb-5 pt-5">
  <div class="class-item col-12 col-md-6 pb-4" data-class-start="1/1/2022" data-class-end="5/28/2022">
    <h5>May 28</h5>
  </div>
  <div class="class-item col-12 col-md-6 pb-4" data-class-start="2/8/2022" data-class-end="3/9/2022">
    <h5>Mar 9</h5>
  </div>
  <div class="class-item col-12 col-md-6 pb-4" data-class-start="1/1/2022" data-class-end="3/5/2022">
    <h5>Mar 5</h5>
  </div>
  <div class="class-item col-12 col-md-6 pb-4" data-class-start="1/1/2022" data-class-end="4/1/2022">
    <h5>Apr 1</h5>
  </div>
  <div class="class-item col-12 col-md-6 pb-4" data-class-start="2/19/2022" data-class-end="3/8/2022">
    <h5>Mar 8</h5>
  </div>
  <div class="class-item col-12 col-md-6 pb-4" data-class-start="2/19/2022" data-class-end="3/24/2022">
    <h5>Mar 24</h5>
  </div>
  <div class="class-item col-12 col-md-6 pb-4" data-class-start="1/1/2022" data-class-end="4/23/2022">
    <h5>Apr 23</h5>
  </div>
  <div class="class-item col-12 col-md-6 pb-4" data-class-start="1/1/2022" data-class-end="4/30/2022">
    <h5>Apr 30</h5>
  </div>
</div>