当链接过滤器并减少时,如何获得过滤后的数组的大小?我需要该尺寸来定制自适应设计CSS。 我的(简化的)代码使用了回调的第3个和第4个参数:
json.articles
.filter(a => keep(a,name))
.reduce((el, a,i,t) =>
i===0? DOMtag('section',{'class':`media${t.length}`})
.appendChild(DOMtag(`article`, content(a,0))).parentElement
: el.appendChild(DOMtag(`article`, content(a,i))).parentElement,
null);
或更简单(由于luc和下面的懒惰评估建议):
json.articles
.filter(a => keep(a,name))
.reduce((el, a,i,t) =>
(el || DOMtag('section',{'class':`media${t.length}`}))
.appendChild(DOMtag(`article`, content(a,i))).parentElement,
null);
两种代码都可以工作,但是如果有人对以某种方式绑定this
有想法,那么可以使用累加器的初始值,例如:
json.articles
.filter(a => keep(a,name))
.reduce((el, a) =>
el.appendChild(DOMtag(`article`, content(a,i))).parentElement,
DOMtag('section',{'class':`media${this.length}`}));
有什么主意吗?
答案 0 :(得分:0)
在传递默认值reduce
时,无法访问已过滤的数组长度,因为该表达式是在调用reduce
之前求值的。
不过,您可以按以下方式简化函数的内容:
// Sample data
const json = {articles: [{name: 'test'},{},{name: 'test2'},{},]};
// functional helper function to illustrate the example
function DOMTag(tagName, {content, className}) {
const tag = document.createElement(tagName);
if (content) {
tag.appendChild(document.createTextNode(content));
}
if (className) {
tag.className = className;
}
return tag;
}
// Start of actual answer code:
const section = json.articles
.filter(a => a.name)
.map(a => DOMTag(`article`, {content: a.name}))
.reduce((p, c, i, a) =>
(p || DOMTag('section',{className:`media${a.length}`}))
.appendChild(c).parentElement
, null);
section.className = `media${section.childNodes.length}`
// Validation
console.log(section.outerHTML);
另一个干净的选择是将className
设置在链外:
// Sample data
const json = {articles: [{name: 'test'},{},{name: 'test2'},{},]};
// functional helper function to illustrate the example
function DOMTag(tagName, content) {
const tag = document.createElement(tagName);
if (content) {
tag.appendChild(document.createTextNode(content));
}
return tag;
}
// Start of actual answer code:
const section = json.articles
.filter(a => a.name)
.map(el => DOMTag('article', el.name))
.reduce((p,c) => (p.appendChild(c), p), DOMTag('section'))
section.className = `media${section.childNodes.length}`
// Validation
console.log(section.outerHTML);
选项2:使用函数抽象化容器的创建:
// Sample data
const json = {articles: [{name: 'test'},{},{name: 'test2'},{},]};
// functional helper function to illustrate the example
function DOMTag(tagName, {content, className}) {
const tag = document.createElement(tagName);
if (content) {
tag.appendChild(document.createTextNode(content));
}
if (className) {
tag.className = className;
}
return tag;
}
// Start of actual answer code:
function section(children) {
const section = DOMTag('section', {
className: `media${children.length}`
});
children.forEach(c => section.appendChild(c));
return section;
}
const s = section(
json.articles
.filter(a => a.name)
.map(el => DOMTag('article', {content: el.name}))
)
// Validation
console.log(s.outerHTML);
选项3:更多功能!如果您绝对必须使用reduce:
// Sample data
const json = {articles: [{name: 'test'},{},{name: 'test2'},{},]};
// functional helper function to illustrate the example
function DOMTag(tagName, {content, className}) {
const tag = document.createElement(tagName);
if (content) {
tag.appendChild(document.createTextNode(content));
}
if (className) {
tag.className = className;
}
return tag;
}
// Start of actual answer code:
function defaultSection() {
let m = false;
return (a = []) => {
if (!m) {
m = DOMTag('section', {className: `media${a.length}`});
}
return m;
};
}
const section = json.articles
.filter(a => a.name)
.map(el => DOMTag('article', {content: el.name}))
.reduce((p,c,i,a) => {
p(a).appendChild(c);
return p;
}, defaultSection())();
// Validation
console.log(section.outerHTML);