循环遍历一个对象及其所有属性,然后移至另一个对象等等的最佳方法是什么?
此刻,我的代码仅循环通过lvlTitle。而我想遍历lvlTitle,然后继续转到statement1,statement2和statement3,然后移至下一个对象。
谢谢。
这是JavaScript:
git pull origin master
这是HTML:
// Different Levels
var lvls = {
start: {
lvlTitle: 'Lets Start!',
},
lvl1: {
lvlTitle: 'Drinks/Soda/water',
statement1: 'lvl1 info...',
statement2: 'lvl1 more info...',
statement3: 'lvl1 more more info...'
},
lvl2: {
lvlTitle: 'Portion Control/Meals',
statement1: 'lvl2 info...',
statement2: 'lvl2 more info...',
statement3: 'lvl2 more more info...'
},
lvl3: {
lvlTitle: 'Salt',
statement1: 'lvl3 info...',
statement2: 'lvl3 more info...',
statement3: 'lvl3 more more info...'
}
}
// Array of all the levels
var allLvls = [];
// Populate users array
for (var key in lvls) {
allLvls.push(lvls[key]);
}
console.log(allLvls[0].lvlTitle);
let myIndex = 1;
let printText = document.querySelector('.text-container');
printText.innerHTML = allLvls[0].lvlTitle;
function nextLevel() {
printText.innerHTML = allLvls[myIndex].lvlTitle;
myIndex = (myIndex + 1) % (allLvls.length);
};
printText.addEventListener('click', nextLevel);
这也是jsFiddle: Iterate through Array List of Objects
答案 0 :(得分:2)
您可以创建一个递归函数。它将创建一个对象并创建一个列表(或您要使用的任何html结构)。在该函数中,查看每个属性,这是一个对象,如果不对其进行处理,则将该对象传递回该函数。这将适用于嵌套在任意深度的对象,这是一个了解的好技术:
// Different Levels
var lvls = {start: {lvlTitle: 'Lets Start!',},lvl1: {lvlTitle: 'Drinks/Soda/water',statement1: 'lvl1 info...',statement2: 'lvl1 more info...',statement3: 'lvl1 more more info...'},lvl2: {lvlTitle: 'Portion Control/Meals',statement1: 'lvl2 info...',statement2: 'lvl2 more info...',statement3: 'lvl2 more more info...'},lvl3: {lvlTitle: 'Salt',statement1: 'lvl3 info...',statement2: 'lvl3 more info...',statement3: 'lvl3 more more info...'}}
function printProps(obj){
let html = "<ul>"
Object.keys(obj).forEach(key => {
html += '<li>' + key + '</li>'
let next = (typeof obj[key] == 'object' ? printProps(obj[key]) : obj[key])
html += '<li>' + next + '</li>'
})
html += "</ul>"
return html
}
let d = document.getElementById('list')
d.innerHTML = printProps(lvls)
<div id = "list"></div>
答案 1 :(得分:1)
对于特殊情况的迭代,您可以使用generator。
生成器是一种相对论新语言功能(ES6),使您能够定义自定义迭代行为,从而使您可以优雅地迭代定制的数据结构,数据集等。
在ES6中,*
符号用于表示函数是生成器,而yield
关键字定义生成器函数如何/何时将值(或多个值)返回给函数。正在生成迭代序列。
根据您的要求,可以如下定义并使用生成器:
/* Define your iterator as follows. Notice the *, which denotes this
function as a generator
*/
function *iterateData(lvlsData) {
// Iterate the values of your input data, ie the objects with
// `lvlTitle` keys
for (const node of Object.values(lvlsData)) {
// Iterate the values of the that you want your application
// to iterate through sequentially
for(var value of Object.values(node)) {
// The yield keyword means "return this value" to the
// external iteration
yield value
}
}
}
var htmlList = '<ul>'
// Use the generator like so, to produce the following output based on
// your data:
for(var str of iterateData(lvls)) {
htmlList += '<li>' + str + '</li>'
}
htmlList += '</ul>'
let d = document.getElementById('list')
d.innerHTML = htmlList;
答案 2 :(得分:1)
基于Mark Meyer's answer和Dacre Denny's answer,我提供了一个递归生成器函数,该函数可迭代对象的嵌套值。我还建议将无限重复封装在高阶迭代器中,以获得更简洁的代码:
const lvls = {start:{lvlTitle:'Lets Start!'},lvl1:{lvlTitle:'Drinks/Soda/water',statement1:'lvl1 info...',statement2:'lvl1 more info...',statement3:'lvl1 more more info...'},lvl2:{lvlTitle:'Portion Control/Meals',statement1:'lvl2 info...',statement2:'lvl2 more info...',statement3:'lvl2 more more info...'},lvl3:{lvlTitle:'Salt',statement1:'lvl3 info...',statement2:'lvl3 more info...',statement3:'lvl3 more more info...'}}
function * deepValuesIterator (o) {
if (typeof o === 'object') {
for (const value of Object.values(o)) {
yield * deepValuesIterator(value)
}
} else {
yield o
}
}
// let's make nextLevel() our infinite iterator
function * nextLevel (levels, generator, element) {
while (true) {
for (const value of generator(levels)) {
yield element.textContent = value
}
}
}
const printText = document.querySelector('.text-container')
const lvlsIterator = nextLevel(lvls, deepValuesIterator, printText)
printText.addEventListener('click', () => lvlsIterator.next())
lvlsIterator.next()
.click-container {
display: flex;
width: 90vw;
height: 12vh;
justify-content: center;
align-items: center;
font-size: calc(14px + (48 - 14) * ((100vw - 300px) / (1600 - 300)));
font-weight: 900;
cursor: pointer;
user-select: none;
}
<div class="full-page">
<div class="click-container">
<ul class="text-container">
<li class="text-content">
<div>
</div>
</li>
</ul>
</div>
</div>
答案 3 :(得分:-1)
object.key将遍历该对象,并使用递归函数遍历另一个对象内的对象。