通过 2 个字典值响应本机搜索
React Native Search by 2 Dictionary Values
我有一些包含两个值的 JSON(见结尾)。我需要根据任一值进行搜索过滤。我记录了 search/display 代码
的每一部分
这是我的 useState 变量:
const [dataBackup, setdataBackup] = useState([]) const [dataSource, setdataSource] = useState([])
这是我的 FlatList:
<SectionList
contentContainerStyle={{ paddingHorizontal: 10}}
stickySectionHeadersEnabled={false}
sections={dataSource}
keyExtractor={(item, index) => {
return index.toString();
}}
renderSectionHeader={({ section }) => (
<>
<Text style={styles.sectionHeader}>{section.title}</Text>
{section.data ? (
<OptimizedFlatList
horizontal
data={section.data}
keyExtractor={(item, index) => {
return index.toString();
}}
renderItem={({ item }) => <ListItem item={item} navigation={navigation} />}
showsHorizontalScrollIndicator={false}
/>
) : null}
</>
)}
renderItem={({ item, section, navigation }) => {
if (section.data) {
return null;
}
return <ListItem item={item} navigation={navigation}/>;
}}
/>
这是不工作过滤逻辑:
filterList = (text) => {
for (let i = 0; i < dataBackup.length; i++) {
const t = dataBackup[i];
newData = t["data"].filter((item) => {
const itemData = item["name"].toLowerCase();
const textData = text.toLowerCase();
setdataSource(itemData.indexOf(textData) > -1)
});
}
}
数据如下:
[{
title: 'Leg',
data:[
{
"bodyPart": "lower legs",
"equipment": "assisted",
"gifUrl": "http://d205bpvrqc9yn1.cloudfront.net/1708.gif",
"id": "1708",
"name": "assisted lying calves stretch",
"target": "calves",
"broad_target": "legs",
"ppl": "legs"
},
{
"bodyPart": "lower legs",
"equipment": "smith machine",
"gifUrl": "http://d205bpvrqc9yn1.cloudfront.net/1396.gif",
"id": "1396",
"name": "smith toe raise",
"target": "calves",
"broad_target": "legs",
"ppl": "legs"
}
]
},
{
title: 'Back',
data:[
{
"bodyPart": "Back",
"equipment": "assisted",
"gifUrl": "http://d205bpvrqc9yn1.cloudfront.net/1708.gif",
"id": "1708",
"name": "Back1",
"target": "Back",
"broad_target": "Back",
"ppl": "Pull"
},
{
"bodyPart": "Back",
"equipment": "smith machine",
"gifUrl": "http://d205bpvrqc9yn1.cloudfront.net/1396.gif",
"id": "1396",
"name": "Back2",
"target": "Back",
"broad_target": "Back",
"ppl": "Pull"
}
]
}]
我希望它按标题或按名称过滤
所以我在您的数据中没有看到标题字段 object。但这是找到完全匹配的方法。该实现用于过滤名称和设备。如果你需要部分匹配,你可以做 item.name.toLowerCase().split(/\s+|./).includes(query.toLowerCase())
const dataSample = [
{ "title": "red",
"data": [{
"bodyPart": "back",
"broad_target": "back",
"equipment": "cable",
"gifUrl": "http://d205bpvrqc9yn1.cloudfront.net/0007.gif",
"id": 1,
"name": "alternate item",
"ppl": "pull",
"target": "lats",
"thumbnail": "https://images.unsplash.com/photo-1640334554717-a7a4ce5d0045?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=296&q=20"
}
]
},
{ "title": "blue",
"data": [{
"bodyPart": "back",
"broad_target": "back",
"equipment": "cable",
"gifUrl": "http://d205bpvrqc9yn1.cloudfront.net/0007.gif",
"id": 1,
"name": "alternate",
"ppl": "pull",
"target": "lats",
"thumbnail": "https://images.unsplash.com/photo-1640334554717-a7a4ce5d0045?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=296&q=20"
}
]
}
]
const filterData = (data = [], query) =>
data.filter(item => item.title.toLowerCase() === query.toLowerCase()
||
item.data.find(element => element.name.toLowerCase() === query.toLowerCase())
)
console.log(filterData(dataSample, 'alternate'))
console.log(filterData(dataSample, 'red'))
试试这个,根据您的评论更新:
const filterData = (data = [], query) =>
data.filter(item => item.title.toLowerCase().includes(query.toLowerCase())
||
item.data.find(element => element.name.toLowerCase().includes(query.toLowerCase()))
)
<SearchBar
onChangeText={(text) =>
text.length !== 0 ?
setdataSource(filterData(dataBackup, text)):
setdataSource(dataBackup)}
onClearPress={() => setdataSource(dataSource)}
/>
当我再考虑一下时,这是涵盖所有其他场景的完美解决方案。
useEffect(() => {
console.log("search key", searchKey)
if(searchKey.length != 0){
setdataSource(filterData(dataBackup, searchKey))
} else{
setdataSource(dataBackup)
}
}, [searchKey])
const filterData = (data = [], query) => {
const foundItems = searchForItem(data, query)
const foundDataItems = searchForDataInItem(data, query)
const uniqueItemTitles = [...new Set([...Object.keys(foundItems),...Object.keys(foundDataItems)])];
return uniqueItemTitles.reduce((title, accumulator) => {
const itemHadTitleMatchedToQuery = foundItems.find(element => element.title === title)
const itemHadDataMatchedToQuery = foundDataItems.find(element => element.title === title)
if(itemHadTitleMatchedToQuery) {
accumulator.push({
...itemHadTitleMatchedToQuery
})
} else {
accumulator.push({
...itemHadDataMatchedToQuery
})
}
return accumulator;
}, []);
}
const searchForItem = (data = [], query) => {
const result = data.filter(item =>
item.title.toLowerCase().includes(query.toLowerCase())
)
return result
}
const searchForDataInItem = (data = [], query) => {
return data.map(item => {
return { ...item, data: item.data.filter(element => element.name.toLowerCase().includes(query.toLowerCase()))}
}).filter(item => item.data.length != 0)
}
在与@Dheeraj Sharma 合作后,我们得出了:
useEffect(() => {
console.log("search key", searchKey)
if(searchKey.length != 0){
setdataSource(filterData(dataBackup, searchKey))
} else{
setdataSource(dataBackup)
}
}, [searchKey])
const filterData = (data = [], query) => {
const foundItems = searchForItem(data, query)
const foundData = searchForDataInItem(data, query)
if(foundItems.length !== 0){
return foundItems;
}
return foundData
}
const searchForItem = (data = [], query) => {
const result = data.filter(item =>
item.title.toLowerCase().includes(query.toLowerCase())
)
return result
}
const searchForDataInItem = (data = [], query) => {
return data.map(item => {
return { ...item, data: item.data.filter(element => element.name.toLowerCase().includes(query.toLowerCase()))}
}).filter(item => item.data.length != 0)
}
我有一些包含两个值的 JSON(见结尾)。我需要根据任一值进行搜索过滤。我记录了 search/display 代码
的每一部分这是我的 useState 变量:
const [dataBackup, setdataBackup] = useState([]) const [dataSource, setdataSource] = useState([])
这是我的 FlatList:
<SectionList
contentContainerStyle={{ paddingHorizontal: 10}}
stickySectionHeadersEnabled={false}
sections={dataSource}
keyExtractor={(item, index) => {
return index.toString();
}}
renderSectionHeader={({ section }) => (
<>
<Text style={styles.sectionHeader}>{section.title}</Text>
{section.data ? (
<OptimizedFlatList
horizontal
data={section.data}
keyExtractor={(item, index) => {
return index.toString();
}}
renderItem={({ item }) => <ListItem item={item} navigation={navigation} />}
showsHorizontalScrollIndicator={false}
/>
) : null}
</>
)}
renderItem={({ item, section, navigation }) => {
if (section.data) {
return null;
}
return <ListItem item={item} navigation={navigation}/>;
}}
/>
这是不工作过滤逻辑:
filterList = (text) => {
for (let i = 0; i < dataBackup.length; i++) {
const t = dataBackup[i];
newData = t["data"].filter((item) => {
const itemData = item["name"].toLowerCase();
const textData = text.toLowerCase();
setdataSource(itemData.indexOf(textData) > -1)
});
}
}
数据如下:
[{
title: 'Leg',
data:[
{
"bodyPart": "lower legs",
"equipment": "assisted",
"gifUrl": "http://d205bpvrqc9yn1.cloudfront.net/1708.gif",
"id": "1708",
"name": "assisted lying calves stretch",
"target": "calves",
"broad_target": "legs",
"ppl": "legs"
},
{
"bodyPart": "lower legs",
"equipment": "smith machine",
"gifUrl": "http://d205bpvrqc9yn1.cloudfront.net/1396.gif",
"id": "1396",
"name": "smith toe raise",
"target": "calves",
"broad_target": "legs",
"ppl": "legs"
}
]
},
{
title: 'Back',
data:[
{
"bodyPart": "Back",
"equipment": "assisted",
"gifUrl": "http://d205bpvrqc9yn1.cloudfront.net/1708.gif",
"id": "1708",
"name": "Back1",
"target": "Back",
"broad_target": "Back",
"ppl": "Pull"
},
{
"bodyPart": "Back",
"equipment": "smith machine",
"gifUrl": "http://d205bpvrqc9yn1.cloudfront.net/1396.gif",
"id": "1396",
"name": "Back2",
"target": "Back",
"broad_target": "Back",
"ppl": "Pull"
}
]
}]
我希望它按标题或按名称过滤
所以我在您的数据中没有看到标题字段 object。但这是找到完全匹配的方法。该实现用于过滤名称和设备。如果你需要部分匹配,你可以做 item.name.toLowerCase().split(/\s+|./).includes(query.toLowerCase())
const dataSample = [
{ "title": "red",
"data": [{
"bodyPart": "back",
"broad_target": "back",
"equipment": "cable",
"gifUrl": "http://d205bpvrqc9yn1.cloudfront.net/0007.gif",
"id": 1,
"name": "alternate item",
"ppl": "pull",
"target": "lats",
"thumbnail": "https://images.unsplash.com/photo-1640334554717-a7a4ce5d0045?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=296&q=20"
}
]
},
{ "title": "blue",
"data": [{
"bodyPart": "back",
"broad_target": "back",
"equipment": "cable",
"gifUrl": "http://d205bpvrqc9yn1.cloudfront.net/0007.gif",
"id": 1,
"name": "alternate",
"ppl": "pull",
"target": "lats",
"thumbnail": "https://images.unsplash.com/photo-1640334554717-a7a4ce5d0045?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=296&q=20"
}
]
}
]
const filterData = (data = [], query) =>
data.filter(item => item.title.toLowerCase() === query.toLowerCase()
||
item.data.find(element => element.name.toLowerCase() === query.toLowerCase())
)
console.log(filterData(dataSample, 'alternate'))
console.log(filterData(dataSample, 'red'))
试试这个,根据您的评论更新:
const filterData = (data = [], query) =>
data.filter(item => item.title.toLowerCase().includes(query.toLowerCase())
||
item.data.find(element => element.name.toLowerCase().includes(query.toLowerCase()))
)
<SearchBar
onChangeText={(text) =>
text.length !== 0 ?
setdataSource(filterData(dataBackup, text)):
setdataSource(dataBackup)}
onClearPress={() => setdataSource(dataSource)}
/>
当我再考虑一下时,这是涵盖所有其他场景的完美解决方案。
useEffect(() => {
console.log("search key", searchKey)
if(searchKey.length != 0){
setdataSource(filterData(dataBackup, searchKey))
} else{
setdataSource(dataBackup)
}
}, [searchKey])
const filterData = (data = [], query) => {
const foundItems = searchForItem(data, query)
const foundDataItems = searchForDataInItem(data, query)
const uniqueItemTitles = [...new Set([...Object.keys(foundItems),...Object.keys(foundDataItems)])];
return uniqueItemTitles.reduce((title, accumulator) => {
const itemHadTitleMatchedToQuery = foundItems.find(element => element.title === title)
const itemHadDataMatchedToQuery = foundDataItems.find(element => element.title === title)
if(itemHadTitleMatchedToQuery) {
accumulator.push({
...itemHadTitleMatchedToQuery
})
} else {
accumulator.push({
...itemHadDataMatchedToQuery
})
}
return accumulator;
}, []);
}
const searchForItem = (data = [], query) => {
const result = data.filter(item =>
item.title.toLowerCase().includes(query.toLowerCase())
)
return result
}
const searchForDataInItem = (data = [], query) => {
return data.map(item => {
return { ...item, data: item.data.filter(element => element.name.toLowerCase().includes(query.toLowerCase()))}
}).filter(item => item.data.length != 0)
}
在与@Dheeraj Sharma 合作后,我们得出了:
useEffect(() => {
console.log("search key", searchKey)
if(searchKey.length != 0){
setdataSource(filterData(dataBackup, searchKey))
} else{
setdataSource(dataBackup)
}
}, [searchKey])
const filterData = (data = [], query) => {
const foundItems = searchForItem(data, query)
const foundData = searchForDataInItem(data, query)
if(foundItems.length !== 0){
return foundItems;
}
return foundData
}
const searchForItem = (data = [], query) => {
const result = data.filter(item =>
item.title.toLowerCase().includes(query.toLowerCase())
)
return result
}
const searchForDataInItem = (data = [], query) => {
return data.map(item => {
return { ...item, data: item.data.filter(element => element.name.toLowerCase().includes(query.toLowerCase()))}
}).filter(item => item.data.length != 0)
}