javascript - 如何以相反的顺序迭代 JavaScript 对象?
问题描述
我有一个包含年份和发布标识符的嵌套对象。如何按年份列出出版物,从最新到最早?我在这里读到,从 ES6 开始,对象的顺序是可预测的。在我的代码中,我有一个函数可以生成年份下拉列表(addOption),另一个函数使用所选年份或所有年份的出版物填充 div(populatePubs)。如果用户选择所有年份,则出版物按从最早到最新(升序)的顺序显示,但我希望出版物按时间倒序显示。是否有内置的 JavaScript 对象方法可以做到这一点?
const testPubs = {
2019 : {
'19-6N': {
'author' : 'jimbo',
'title' : 'test title'
},
'19-7N': {
'author' : 'jimmy',
'title' : 'test title 2'
}
},
2018 : {
'18-6N': {
'author' : 'joey',
'title' : 'test title'
},
'18-7N': {
'author' : 'jeffy',
'title' : 'test title 2'
}
},
2017 : {
'17-6N': {
'author' : 'bob',
'title' : 'test title'
},
'17-7N': {
'author' : 'bobby',
'title' : 'test title 2'
}
},
}
const startYear = 1984;
const currentYear = new Date().getFullYear();
function addOption() { // adds years to dropdown menu
const select = document.querySelector('#selectYears');
let blank_option = document.createElement("option");
blank_option.setAttribute("selected", true);
blank_option.setAttribute("disabled", true);
blank_option.textContent = `Year`;
select.appendChild(blank_option);
for (let i = currentYear; i >= startYear; i--){
let option = i;
let el = document.createElement("option");
el.textContent = option;
select.appendChild(el);
}
const allYears = document.createElement("option");
allYears.textContent = `All Years`;
select.appendChild(allYears)
}
addOption(); // add years dropdown
function populatePubs(year){
const pubsForYear = document.querySelector("#pubsByYear");
pubsByYear.class = year;
while (pubsForYear.firstChild){
pubsByYear.removeChild(pubsByYear.firstChild);
}
if (year in testPubs){
for (let pub in testPubs[year]){ // add publications for specified year
let doc = document.createElement("div");
doc.id = pub;
doc.textContent = `${testPubs[year][pub].author} - ${testPubs[year][pub].title} - ${pub}`;
pubsByYear.appendChild(doc);
}
} else if (year === 'All Years') { // need to ensure order of object is descending
for (let yr in testPubs){ // add publications for all years
const yearHeader = document.createElement("h4");
yearHeader.innerText = yr;
pubsByYear.appendChild(yearHeader);
if (typeof testPubs[yr] === 'object'){
for (let pub in testPubs[yr]) {
pubsByYear.class = `All Years`;
const doc = document.createElement("div");
doc.id = testPubs[yr][pub];
doc.textContent = `${testPubs[yr][pub].author} - ${testPubs[yr][pub].title} - ${pub}`;
pubsByYear.appendChild(doc);
}
}
}
}
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Test Publications by Year</title>
<body>
<!-- years dropdown -->
<select id="selectYears" onchange="populatePubs(this.value)"></select>
<!-- display current year -->
<div id="pubsByYear" class="year"></div>
<script src="script.js"></script>
</body>
</html>
解决方案
您可以结合 Object.keys 方法在数组上使用内置的 reverse 方法:
function populatePubs(year) {
const pubsForYear = document.querySelector("#pubsByYear");
pubsByYear.class = year;
while (pubsForYear.firstChild) {
pubsByYear.removeChild(pubsByYear.firstChild);
}
if (year in testPubs) {
for (let pub in testPubs[year]) { // add publications for specified year
let doc = document.createElement("div");
doc.id = pub;
doc.textContent = `${testPubs[year][pub].author} - ${testPubs[year][pub].title} - ${pub}`;
pubsByYear.appendChild(doc);
}
} else if (year === 'All Years') { // need to ensure order of object is descending
const years = Object.keys(testPubs).reverse();
for (let yr of years) { // add publications for all years
const yearHeader = document.createElement("h4");
yearHeader.innerText = yr;
pubsByYear.appendChild(yearHeader);
if (typeof testPubs[yr] === 'object') {
for (let pub in testPubs[yr]) {
pubsByYear.class = `All Years`;
const doc = document.createElement("div");
doc.id = testPubs[yr][pub];
doc.textContent = `${testPubs[yr][pub].author} - ${testPubs[yr][pub].title} - ${pub}`;
pubsByYear.appendChild(doc);
}
}
}
}
}
推荐阅读
- r-lavaan - 比较非嵌套模型之间的标准化因子载荷
- python - 熊猫在最后一个空格后删除数据
- google-apps-script - 如何在谷歌应用脚本中使用 Drive v3?
- c# - 实体框架:连接两个表和 where 子句
- sqlite - 使用包含空格的命名参数准备 SQLite 语句
- reactjs - 从源“http://localhost:3000”访问...的 XMLHttpRequest 已被 CORS 策略阻止
- electron - 将 Blazor 与 Electron.NET 结合使用,当我单击 MenuItem 时,如何在组件内执行代码?
- cadence-workflow - 如何在不等待的情况下获得 Activity 的结果?以事件驱动的方式
- php - 根据总分、最高分和全球、国家、省份优化 MySQL 聚合排名和排行榜查询
- python - Tkinter:检索单选按钮列和行值