javascript - 如何对json数组值进行排序?
问题描述
我想将此 json 转换为具有排序日期的 html 表。基本上我的 JSON 数据看起来像这样:
在这里我要重复列出日期
var frequencyList= [
{
"project": "abc",
"recurrenceList": [
"2021-09-16",
"2023-09-16",
"2025-09-16"
]
},
{
"project": "xyz",
"recurrenceList": [
"2021-08-23",
"2025-08-23"
]
},
{
"project": "mno",
"recurrenceList": [
"2021-09-11",
"2022-05-11",
"2023-01-11",
"2023-09-11",
"2024-05-11",
"2025-01-11",
"2025-09-11"
]
}
]
我 在 html 表中得到了这样的输出,下面给出了两列(基于上面的 JSON)
project name reminder date
xyz 2021-08-23
mno 2021-09-11
abc 2021-09-16
mno 2022-05-11
ETC...
下面是 Ajax 获取 JSON DATA 频率列表的代码
/* the getPaymentPlan function is standalone, it should not be within a loop or within any other callback functions! */
const getPaymentPlan = ({
dateFrom,
dateTo,
recurrenceDate,
daysBefore,
period,
skip,
title
}) => {
//start from either the recurrence start date, or the start date in the form - whichever is later
let startDate = (recurrenceDate.getTime() > dateFrom.getTime() ? recurrenceDate : dateFrom);
//reminders go out several days before the actual recurrence start date
startDate = startDate.subtractDays(daysBefore);
let recurObj = {
"project": title,
"recurrenceList": []
}
while (startDate.getTime() <= dateTo.getTime()) {
recurObj.recurrenceList.push(startDate.toISOString().split('T')[0]);
switch (period) {
case 'Monthly':
startDate = startDate.addMonths(parseInt(skip));
break;
case 'Yearly':
startDate.setFullYear(startDate.getFullYear() + parseInt(skip));
break;
default:
recurObj.recurrenceList.push("wrong period type is given")
break;
}
}
return recurObj;
}
/* below are some functions to correctly add / subtract days and months from a Date, accounting for leap years, differing month lengths, etc */
Date.prototype.addDays = function(days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() + days);
return date;
}
Date.prototype.subtractDays = function(days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() - days);
return date;
}
Date.prototype.addMonths = function(months) {
var date = new Date(this.valueOf());
var d = date.getDate();
date.setMonth(date.getMonth() + months);
if (date.getDate() != d) {
date.setDate(0);
}
return date;
}
$('#find_recurrence').click(function(event) {
$('.tableinvoicelist_all').find('tbody').remove();
var getID_comp = $('#getID_comp').val();
var fromdate_recu_viewedit = $('#fromdate_recu_view').val(); //2025-01-01
var fromdate_recu_view = fromdate_recu_viewedit.split("-").reverse().join("-");
var todate_recu_viewedit = $('#todate_recu_view').val(); //2026-01-30
var todate_recu_view = todate_recu_viewedit.split("-").reverse().join("-");
//hard-code data instead of AJAX, for this demo:
$.ajax({
url: base_url + "index.php/welcome/list_all_projects_reminder/",
type: "POST",
data: {
"company_id": getID_comp
},
success: function(data) {
var new_datajson = JSON.parse(data);
let new_data = new_datajson;
let inputList = [];
for (var i = 0; i < new_data.projectremindshow.length; i++) {
var proj = new_data.projectremindshow[i];
//add a new entry to inputList for each entry returned from the AJAX call
inputList.push({
dateFrom: new Date(fromdate_recu_view),
dateTo: new Date(todate_recu_view),
daysBefore: proj.reminder_set_days,
recurrenceDate: new Date(proj.start_date),
period: proj.period_type,
skip: proj.recur_every,
title: proj.project_title
});
}
const frequencyList = inputList.map((el, index) => {
return getPaymentPlan(el)
});
console.log(frequencyList);
$.each(frequencyList, function(index, jsonObject){
if(Object.keys(jsonObject).length > 0){
var tableRow = '<tr>';
$.each(Object.keys(jsonObject), function(i, key){
tableRow += '<td>' + jsonObject[key] + '</td>';
});
tableRow += "</tr>";
$("#tablereminder").last().append(tableRow);
}
});
}
})
});
如何更改一个列表而不是三个列表(recurrenceList)中的列表?按日期排序
解决方案
这是 getPaymentPlan 函数的替代版本,它将以更易于排序的格式输出数据,并且稍后根据您所需的 HTML 格式输出:
const getPaymentPlan = ({
dateFrom,
dateTo,
recurrenceDate,
daysBefore,
period,
skip,
title
}) => {
//start from either the recurrence start date, or the start date in the form - whichever is later
let startDate = (recurrenceDate.getTime() > dateFrom.getTime() ? recurrenceDate : dateFrom);
//reminders go out several days before the actual recurrence start date
startDate = startDate.subtractDays(daysBefore);
let recurrenceList = [];
while (startDate.getTime() <= dateTo.getTime()) {
recurrenceList.push({ "project": title, "reminderDate": startDate.toISOString().split('T')[0] });
switch (period) {
case 'Monthly':
startDate = startDate.addMonths(parseInt(skip));
break;
case 'Yearly':
startDate.setFullYear(startDate.getFullYear() + parseInt(skip));
break;
default:
recurrenceList.push({ "project": "wrong period type is given", "reminderDate": null })
break;
}
}
return recurrenceList;
}
然后,您可以使用类似于早期问题中可用示例的比较函数对其进行排序,例如:
function compare( a, b ) {
if ( a.reminderDate < b.reminderDate ){
return -1;
}
if ( a.reminderDate > b.reminderDate){
return 1;
}
return 0;
}
recurrenceList.sort( compare );
完成后,您可以遍历列表以生成 HTML 表格:
$.each(frequencyList, function(index, jsonObject){
var tableRow = '<tr>';
$.each(Object.keys(jsonObject), function(i, key){
tableRow += '<td>' + jsonObject[key] + '</td>';
});
tableRow += "</tr>";
$("#tablereminder").last().append(tableRow);
});
将它们放在一个演示中,您可以获得所需的输出:
$('#find_recurrence').click(function(event) {
var fromdate_recu_view = $('#fromdate_recu_view').val(); //2025-01-01
var todate_recu_view = $('#todate_recu_view').val(); //2026-01-30
//hard-code data instead of AJAX, for this demo:
let new_data = {
"projectremindshow": [{
"project_ID": "8",
"project_title": "abc",
"period_type": "Yearly",
"recurrence_date": "2021-10-28",
"reminder_set_days": "12",
"recur_every": "2",
"start_date": "2021-09-28"
},
{
"project_ID": "10",
"project_title": "xyz",
"period_type": "Yearly",
"recurrence_date": "2021-10-05",
"reminder_set_days": "13",
"recur_every": "4",
"start_date": "2021-09-05"
},
{
"project_ID": "11",
"project_title": "mno",
"period_type": "Monthly",
"recurrence_date": "2021-10-01",
"reminder_set_days": "10",
"recur_every": "8",
"start_date": "2021-09-21"
}
]
};
let inputList = [];
for (var i = 0; i < new_data.projectremindshow.length; i++) {
var proj = new_data.projectremindshow[i];
//add a new entry to inputList for each entry returned from the AJAX call
inputList.push({
dateFrom: new Date(fromdate_recu_view),
dateTo: new Date(todate_recu_view),
daysBefore: proj.reminder_set_days,
recurrenceDate: new Date(proj.start_date),
period: proj.period_type,
skip: proj.recur_every,
title: proj.project_title
});
}
let frequencyList = [];
for (let i = 0; i < inputList.length; i++)
{
let plan = getPaymentPlan(inputList[i]);
Array.prototype.push.apply(frequencyList,plan);
}
console.log(frequencyList);
frequencyList.sort(compare);
$.each(frequencyList, function(index, jsonObject) {
var tableRow = '<tr>';
$.each(Object.keys(jsonObject), function(i, key) {
tableRow += '<td>' + jsonObject[key] + '</td>';
});
tableRow += "</tr>";
$("#tablereminder").last().append(tableRow);
});
});
const getPaymentPlan = ({
dateFrom,
dateTo,
recurrenceDate,
daysBefore,
period,
skip,
title
}) => {
//start from either the recurrence start date, or the start date in the form - whichever is later
let startDate = (recurrenceDate.getTime() > dateFrom.getTime() ? recurrenceDate : dateFrom);
//reminders go out several days before the actual recurrence start date
startDate = startDate.subtractDays(daysBefore);
let recurrenceList = [];
while (startDate.getTime() <= dateTo.getTime()) {
recurrenceList.push({
"project": title,
"reminderDate": startDate.toISOString().split('T')[0]
});
switch (period) {
case 'Monthly':
startDate = startDate.addMonths(parseInt(skip));
break;
case 'Yearly':
startDate.setFullYear(startDate.getFullYear() + parseInt(skip));
break;
default:
recurrenceList.push({
"project": "wrong period type is given",
"reminderDate": null
})
break;
}
}
return recurrenceList;
}
function compare(a, b) {
if (a.reminderDate < b.reminderDate) {
return -1;
}
if (a.reminderDate > b.reminderDate) {
return 1;
}
return 0;
}
Date.prototype.addDays = function(days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() + days);
return date;
}
Date.prototype.subtractDays = function(days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() - days);
return date;
}
Date.prototype.addMonths = function(months) {
var date = new Date(this.valueOf());
var d = date.getDate();
date.setMonth(date.getMonth() + months);
if (date.getDate() != d) {
date.setDate(0);
}
return date;
}
#tablereminder
{
border: solid 1px black;
padding: 5px;
border-collapse: collapse;
}
#tablereminder td
{
border: solid 1px black;
padding: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
From date: <input type="date" id="fromdate_recu_view" /><br/> To date: <input type="date" id="todate_recu_view"><br/>
<button id="find_recurrence">Find Recurrence</button>
<br/><br/>
<table id="tablereminder"></table>
(您可能需要以全页模式查看演示以查看表格以及控制台的调试输出。)
推荐阅读
- java - 具有 0 个或多个任意类型参数的 Spring AOP 切入点表达式方法抛出 java.lang.NullPointerException
- java - 如何解决这个 Maven 多模块依赖问题?安装后没有从本地 m2 导入
- kubernetes - Gloo gateway-proxy GKE 上的外部 IP:telnet:无法连接到远程主机:连接被拒绝
- haskell - 避免在不变有向图中重新访问节点
- android - 在滚动视图中添加两个线性布局,布局要么收缩要么压缩。在这里,我在其中使用 layout_weight 这就是出现问题的原因
- typescript - 如何使用 CDK 为 Typescript 配置发送(apigateway)和获取(lambda)请求查询参数
- node.js - 如何使用 Mongoose 将键:值对添加到现有的 Mongodb 对象
- python - Python glob 模块不适用于多选?
- ios - 在 iOS 中谷歌登录后无法获取 Authcode (swift)
- java - 如何将从相机或画廊获取的图像传递到另一个活动