这个想法非常简单。
在一个计算变量中,我想使用needle过滤部分,但我不想只显示匹配的部分和附加的问题(就像下面的例子中一样(,我想排除标题不匹配和部分标题不匹配的问题。
以下是初始数据集:
const sections =
[
{
title: 'Title section 1',
questions : [
{
title: 'Title question 1'
},
{
title: 'Title question 2'
}
]
},
{
title: 'Title section 2',
questions : [
{
title: 'Title question 3'
},
{
title: 'Title question 4'
}
]
}
]
以下是预期结果:
当指针处于"区段1"时:
const filteredArray = [
{
title: 'Title section 1',
questions : [
{
title: 'Title question 1'
},
{
title: 'Title question 2'
}
]
}
]
当指针为"问题1"时:
const filteredArray = [
{
title: 'Title section 1',
questions : [
{
title: 'Title question 1'
}
]
}
]
等等。
这是我写的代码:
const sections =
[
{
title: 'Title section 1',
questions : [
{
title: 'Title question 1'
},
{
title: 'Title question 2'
}
]
},
{
title: 'Title section 2',
questions : [
{
title: 'Title question 3'
},
{
title: 'Title question 4'
}
]
}
]
const needle = 'question 4'
const filteredArray = sections.filter(section => section.title.toLowerCase().indexOf(needle.toLowerCase()) !== -1 ||
section.questions.filter(question => question.title.toLowerCase().indexOf(needle.toLowerCase()) !== -1).length > 0)
console.log(filteredArray)
正如你所看到的,过滤后的结果是好的,但当问题标题和部分标题不匹配时,我不能排除问题。
一个主意?
注意:我使用的是vuejs 2,所以我的原始数组是从存储中混合而来的,为了保持反应性,我不能使用其他数组。
我会使用Array.prototype.reduce来实现这样的结果:
const needleTitle = 'section 2'
const needleQuestion = 'question 4'
const filteredArray = sections.reduce((acc, section) => {
// filtering 1-level section list by pushing to acc only needed items
if (section.title.toLowerCase().indexOf(needleTitle.toLowerCase()) >= 0) {
// filtering 2-level question list by replacing section.questions with a new list
const questions = section.questions.filter(question =>
question.title.toLowerCase().indexOf(needleQuestion.toLowerCase()) >= 0
)
acc.push({ ...section, questions });
}
return acc;
}, []);
另外,您可以看到,我将needle
拆分为needleTitle
和needleQuestion
。也许这并不完全是你想要的,但这个想法应该是有用的。上面的代码将导致
[
{
title: 'Title section 2',
questions : [
{
title: 'Title question 4'
}
]
}
]
感谢@dhilt,这里是最终解决方案:(
const sections =
[
{
title: 'Title section 1',
questions : [
{
title: 'Title question 1'
},
{
title: 'Title question 2'
}
]
},
{
title: 'Title section 2',
questions : [
{
title: 'Title question 3'
},
{
title: 'Title question 4'
}
]
}
]
const needle = 'question 4'
const filteredArray = sections.reduce((acc, section) => {
// Pushing entire section if we find needle in section title
if (section.title.toLowerCase().indexOf(needle.toLowerCase()) >= 0) {
acc.push({ ...section })
} else {
// Pushing section with filtered questions when question title match
const questions = section.questions.filter(question =>
question.title.toLowerCase().indexOf(needle.toLowerCase()) >= 0
)
if (questions.length > 0) {
acc.push({ ...section, questions })
}
}
return acc
}, [])
console.log(filteredArray)