我有一个需要过滤的对象数组。
如果对象的活动值为true,则无论其他因素如何,都应始终返回该值。
如果输入了searchText,则应通过此搜索文本过滤列表的其余部分。
如果输入了countrySearch,则应按此值过滤列表,如果提供了该列,则也应过滤searchText。
const searchText = 'Di';
const countrySearch = "USA";
const myArray = [
{
name: "Tom",
country: "UK",
active: true
},
{
name: "Dick",
country: "USA",
active: false
},
{
name: "Dimmon",
country: "FR",
active: false
}
].filter(item => {
if (item.active === true) {
return true;
}
if (searchText) {
if(item.name.includes(searchText)) {
return true;
}
}
});
console.log(myArray);
在此示例中,新数组应包含Tom,因为active为true。它应该包含Dick,因为他通过了searchText和countrySearch测试。 Dimmon不应该在新数组中,因为他只传递了searchText和countrySearch搜索条件中的一个。
我可以使用我当前的方法来解决这个问题,但是使用嵌套的if语句会让它变得混乱。此外,我的搜索条件可能会随着时间的推移而增加。这是函数式编程的好例子吗?
答案 0 :(得分:1)
以下是使用transducers
执行此操作的另一种方法
const comp = ( f , g ) =>
x => f ( g ( x ) )
const compose = ( ...fs ) =>
fs.reduce ( comp , x => x )
const append = ( xs , x ) =>
xs.concat ( [ x ] )
const transduce = ( ...ts ) => xs =>
xs.reduce ( ts.reduce ( comp ) ( append ) , [] )
const filterer = f =>
k => ( acc , x ) => f ( x ) ? k ( acc , x ) : acc
const search = ( query , country, items ) =>
transduce ( filterer ( x => x.active === true )
, filterer ( x => x.name.includes ( query ) )
, filterer ( x => x.country === country )
) (items)
const data0 =
[ { name: 'Tom'
, country: 'UK'
, active: true
}
, { name: 'Dick'
, country: 'USA'
, active: true
}
, { name: 'Dimmon'
, country: 'FR'
, active: false
}
]
console.log ( search ( 'Di', 'USA', data0 ) )
// [ { name: 'Dick'
// , country: 'USA'
// , active: true
// }
// ]

如果您不想要通用程序附带的仪式,您可以随时构建完全专有的API
const run = ( value = [] ) =>
( { type : run
, value : value
}
)
const filterer = f => g =>
g && g.type === run
? g.value.filter ( x => f ( x ) )
: filterer ( x => f ( x ) && g ( x ) )
const search = ( query , country , items ) =>
filterer ( x => x.active === true )
( x => x.name.includes ( query ) )
( x => x.country === country )
( run ( items ) )
const data0 =
[ { name: 'Tom'
, country: 'UK'
, active: true
}
, { name: 'Dick'
, country: 'USA'
, active: true
}
, { name: 'Dimmon'
, country: 'FR'
, active: false
}
]
console.log ( search ( 'Di', 'USA', data0 ) )
// [ { name: 'Dick'
// , country: 'USA'
// , active: true
// }
// ]

答案 1 :(得分:0)
根据您的搜索方法,您可以简化代码,如下所示。
首先使用OR子句搜索连接条件。它只是查看active
属性设置为true
, OR 名称属性包含 Di lexem的对象数组 - 因此所有三个对象都匹配。< / p>
第二个也执行相同的操作,但这次使用 AND 子句,结果为空数组。因为没有任何对象一次处理两个条件。
const searchText = 'Di';
const countrySearch = "USA";
const myArray = [
{
name: "Tom",
country: "UK",
active: true
},
{
name: "Dick",
country: "USA",
active: false
},
{
name: "Dimmon",
country: "FR",
active: false
}
]
console.log('OR')
console.log(myArray.filter(e => e.active || e.name.includes(searchText)));
console.log('AND')
console.log(myArray.filter(e => e.active && e.name.includes(searchText)));
答案 2 :(得分:0)
根据您可以使用active
的预期逻辑,OR
countrySearch
AND
countrySearch
等于country
AND
{ {1}} searchText
AND
name
.includes()
,searchText
OR
searchText
AND
为{{1} } countrySearch
false
AND
name
,.includes()
searchText
为OR
searchText
false
{{ 1}} AND
等于countrySearch
AND
&#13;
答案 3 :(得分:0)
创建一个函数并传递searchText
&amp; countrySearch
。 filter
函数的返回值取决于countrySearch
const searchText = 'Di';
const countrySearch = "USA";
const myArray = [
{
name: "Tom",
country: "UK",
active: true
},
{
name: "Dick",
country: "USA",
active: false
},
{
name: "Dimmon",
country: "FR",
active: false
}
]
function getFilterResult(b, c) {
return myArray.filter(function(a, d) {
// if countrySearch is undefined then return only active & name
// which pass the searchText, else return where all the conditions match
return void 0 === c ? a.active || a.name.includes(b) :
a.active || a.name.includes(b) && a.country === c;
});
};
console.log(getFilterResult(searchText,countrySearch));
答案 4 :(得分:0)
在此示例中,新数组应包含 Tom,因为 active 为真。 当他通过 searchText 和 countrySearch 时,它应该包含 Dick 测试。 Dimmon 不应该在新数组中,因为他只传递了 1 个 searchText 和 countrySearch 搜索条件。
const searchText = 'Di';
const countrySearch = "USA";
const myArray = [
{
name: "Tom",
country: "UK",
active: true
},{
name: "Dick",
country: "USA",
active: false
},{
name: "Dimmon",
country: "FR",
active: false
}
].filter(item => item.active || (item.name.includes(searchText)
&& item.country.valueOf() === countrySearch.valueOf() ));
document.write(JSON.stringify(myArray));
答案 5 :(得分:-1)
尝试:
.filter(item => {
if (
(item.active === true) ||
(searchText && item.name.includes(searchText))
) {
return true;
}
}
})