我编写了一个javascript函数,该函数成功返回HTML文档中使用的所有唯一类的数组。
const elements = document.getElementsByTagName('*');
let classesUsedInHtml = htmlCollection => {
let uniqClassSelectors = [];
Array.from(htmlCollection)
.filter(element => element.classList.length > 0)
.map(element =>
element.classList.forEach(
item =>
uniqClassSelectors.includes(item)
? null
: uniqClassSelectors.push(item)
)
);
return uniqClassSelectors;
};
console.log(classesUsedInHtml(elements));
我想使用Array.prototype.reduce()
重构此函数,并且不需要定义变量uniqClassSelectors
,但无法使其正常工作。
这是我的重构函数不起作用(返回accumulator is undefined
)。在这方面,我常常被reduce()
绊倒。为什么accumulator
未定义?我没有在forEach()
函数中正确使用reduce()
吗?任何人都能指出我在正确的方向吗?谢谢!
let classesUsedInHtml = htmlCollection => {
return Array.from(htmlCollection)
.filter(element => element.classList.length > 0)
.reduce((accumulator, element) => {
return element.classList.forEach(
classSelector =>
accumulator.includes(classSelector)
? accumulator
: accumulator.concat(classSelector)
);
}, []);
};
编辑:由于Nina Scholz的评论,从相关函数中移除了不必要的map()
答案 0 :(得分:2)
我建议使用另一个内部累加器作为最终domTokenList
,并将外部accumulator
作为内部累加器acc2
的起始值。
let classesUsedInHtml = htmlCollection =>
Array
.from(htmlCollection)
.filter(element => element.classList.length)
.map(element => element.classList)
.reduce((accumulator, domTokenList) =>
domTokenList.reduce((acc2, classSelector) =>
acc2.concat(acc2.includes(classSelector) ? [] : classSelector),
accumulator
),
[]
);
另一个解决方案可能是使用Set
来收集唯一的类选择器。
let classesUsedInHtml = htmlCollection =>
[...Array
.from(htmlCollection)
.filter(element => element.classList.length)
.map(element => element.classList)
.reduce((acc1, domTokenList) =>
domTokenList.reduce((acc2, classSelector) => acc2.add(classSelector), acc1),
new Set)
];
答案 1 :(得分:1)
此解决方案的分步指南。注释(// - >)显示此步骤的结果,该步骤将传递给下一步。
htmlCollection
转换为数组
[...htmlCollection] // -> [htmlElement, htmlElement, etc...]
Array#map每个元素到一个类数组(再次传播):
[htmlElement, htmlElement, etc...].map(({ classList }) => [...classList])) // -> [[class, class, etc...], [class, class, etc...], etc...]
通过传播到Array#concat:
来展平子阵列[].concat(...[[class, class, etc...], [class, class, etc...]], etc...) // -> [class, class, class, etc...]
将数组转换为Set,然后传播回数组,以获取唯一的类名:
[...new Set([class, class, class, etc...])] // -> [class1, class2, class3, etc...]
const elements = document.getElementsByTagName('*');
const classesUsedInHtml = (htmlCollection) =>
[...new Set( // get unique items and convert to array
[].concat(... // concat all classes' arrays
[...htmlCollection] // convert the collection to an array
.map(({ classList }) => [...classList])) // get arrays of classes
)
];
const result = classesUsedInHtml(elements);
console.log(result);

<div class="a c">
<span class="a b"></span>
<span class="b c"></span>
</div>
&#13;