通过 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)
}