【问题标题】:Matching properties of objects in two different arrays匹配两个不同数组中对象的属性
【发布时间】:2021-01-27 22:48:32
【问题描述】:

背景

我正在为我正在开发的应用程序构建一个“喜欢的商店”屏幕。此屏幕呈现flatlist,其中显示了用户喜欢的每个商店的卡片。我处理该过程的方式是,当用户喜欢商店时,它会在 firestore 中创建一个新文档,其中包含商店的 id 和“喜欢”boolean

问题

我一直在尝试过滤我的数据库中的商店总数,并将喜欢的商店的 id 与“喜欢”集合文档中的 id 匹配。

数据结构为:

user/uid/favorites,这里的每个文档都包含 2 个字段。一个 id(与 stores/ 集合中的另一个 id 匹配)和一个布尔值,表明它已被点赞。然后stores/ 的文档包含大量数据,但这里重要的是一个包含 id 的字段。

我尝试实现以下解决方案,两个订阅者带来每个集合和一个处理过滤的函数。但由于某种原因,我不太明白我只是无法让它工作。

代码如下:

const [stores, setStores] = useState([]);
     useEffect(() => {
        const subscriber = firebase.firestore()
        .collection('stores/')
        .onSnapshot(querySnapshot => {
          const stores = [];
    
          querySnapshot.forEach(documentSnapshot => {
            stores.push({
              ...documentSnapshot.data(),
              key: documentSnapshot.id,
            });
          });
    
          setStores(stores);
        });
    
      return () => subscriber();
    }, [])

    const [liked, setLiked] = useState([]);

    useEffect(() => {
        const subscriber = firebase.firestore()
        .collection('users/' + userId + '/favorites')
        .onSnapshot(querySnapshot => {
          const liked = [];
    
          querySnapshot.forEach(documentSnapshot => {
            liked.push({
              ...documentSnapshot.data(),
              key: documentSnapshot.id,
            });
          });
    
          setLiked(liked);
        });
    
      return () => subscriber();
    }, [])
    
    const usefulData = [];
      const handleFilter = (obj) => {
       for(let i = 0; i < stores.length; i++){
        if(obj.id === liked[i].storeId) {
            usefulData.push(obj)
        }
       }
    }
        stores.filter(handleFilter);

然后我将 usefulData 作为数据参数传递给 FlatList。

打印有用数据时,它只返回一个空数组。

问题

谁能提供一个解决方案和解释为什么这不起作用以及如何正确比较两个对象数组的值?

【问题讨论】:

  • 如果没有实际数据(要弄清楚它的结构),回答您的问题可能会很棘手。
  • @YevgenGorbunkov Gorbunkov 添加了我猜你指的数据。
  • 如果您能提供您的 Firestore 数据库的屏幕截图,那就太好了。这样就更容易理解您想要实现的目标并改进您的解决方案。

标签: javascript firebase react-native google-cloud-firestore


【解决方案1】:

嗯,以最不舒服和最不优雅的方式解决了这个问题,所以任何提示或更好的想法仍然会被人们深情地接受:

const likedIds = [];
    liked.forEach(o => likedIds.push(o.id));
    const storeIds = [];
    stores.forEach(o => storeIds.push(o.id));
    
    const intersection = storeIds.filter(element => likedIds.includes(element));

    const [data, setData] = useState([]);
    const finalArray = [];
    useEffect(() => {
    for (let i = 0; i < intersection.length; i++){
      const fetchQuery = async () => {
        
        const storeData = await firebase.firestore()
        .collection('stores/')
        .doc(intersection[i])
        .get()
        .then(documentSnapshot => {
          if (documentSnapshot.exists) {
            finalArray.push(documentSnapshot.data())

          }
        });
        setData(finalArray)
      }
      fetchQuery()
      
    }
  
    }, [])

在不改变问题中提出的任何其他内容的情况下,这就是我为使其正常工作而添加的内容。首先,我从每个对象数组中获取所有 Id,然后过滤它们并将它们存储在一个新数组中。然后我们可以继续使用方便的 fetchQuery 异步函数构建一个新的对象数组,以从原始 stores 集合中获取所有数据,只是这一次它只显示了 intersection 数组中具有 ids 的商店。

我完全清楚这是最可靠和最令人作呕的解决方案,但至少它有效。希望比我聪明的人能从中得到一些帮助,让我的解决方案变得更好!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    相关资源
    最近更新 更多