【问题标题】:javascript find object in object-array though specific object propertyjavascript 通过特定的对象属性在对象数组中查找对象
【发布时间】:2016-07-26 21:08:48
【问题描述】:

我有一个这样的线程对象数组

threadlist:Thread[]= [thread{id:1},thread{id:2},thread{id:3},...]

我在用户对象中也有一个 ThreadRelation 数组,如下所示,用于存储用户是否为某个线程添加了书签。 请注意,Thread 中的 id 与其在数组中的位置不匹配。

user{
  user_id:number,...(some other user typical properties)
  threadRelations:ThreadRelation[]=[
  threadRelation{
    id:2,//relates to id property of a Thread object
    isBookmarked:true
  },
  threadRelation{
    id:18,
    isBookmarked:true
  },..
]}

我想创建一个函数,它返回一个仅包含用户书签线程的数组。我可以使用两个 for 循环和 if 语句来实现这一点,但我认为它效率不高。 是否有一些方法可以让我直接在数组中找到该特定对象?

updateBookmarkedList(){
      for (var i = 0; i < this.activeUser.threadsRelation.length; i++){
        if ( this.activeUser.threadsRelation[i].bookmarked == true){
          var searchId = this.activeUser.threadsRelation[i].id;
          for (var j = 0; j < this.threadlist.length; j++){
            if (this.threadlist[j].id == searchId){
              this.userBookmarkedList.push(this.threadlist[j])
            }
          }
        }
      }
  }

谢谢!

【问题讨论】:

  • 使用Array.prototype.filter!附带说明,您的 JSON 无效,除非这是伪代码。在这种情况下,您应该提供您拥有的完整示例(使用有效数据)。
  • @Mr.Polywhirl 考虑将此作为答案。

标签: javascript arrays sorting typescript


【解决方案1】:

如果Thread.id 是唯一标识符,那么您确实应该使用Map 而不是Array 的没有键的对象。如果没有键,您将不得不在没有其他选择的情况下迭代数组。

在迭代Array 时,请尝试使用内置的迭代方法,例如forEach。它们比循环更高效,看起来更整洁。

为了补充@Tamas-Hegedus's answer using ES6 iterator feature,我使用当前版本的JavaScript创建了一个JSFiddle来制作“Array-Map”,如果Thread.id不是数字,你可以用Map替换它。

JSFiddle

【讨论】:

    【解决方案2】:

    您为什么不按 id 保存“线程”的地图?

    从数组创建地图:

    var threadsById = new Map(threads.map(t => [t.id, t]));
    

    获取是否存在threadid:

    if (threadsById.has(threadRelation.id)) {
      ...
    }
    

    通过 id 获取线程:

    var currentThread = threadsById.get(threadRelation.id);
    

    【讨论】:

      【解决方案3】:

      使用Array.prototype.filter,您只能保留已添加书签的线程关系。从此过滤列表中,您可以根据id 标准构建线程列表。

      var threads = [
        { id: 1 },
        { id: 2 },
        { id: 3 }
      ];
      
      var users = [{
        user_id: 1,
        threadRelations: [
          { id: 2,  isBookmarked: true },
          { id: 18, isBookmarked: true }
        ]
      }];
      
      var userBookmarkedList = updateBookmarkedList(users[0], threads);
      document.body.innerHTML = '<pre>Threads -> ' + JSON.stringify(userBookmarkedList, null, 2) + '</pre>';
      
      function updateBookmarkedList(user, threads) {
        return user.threadRelations.filter(function(threadRelation) {
          return threadRelation.isBookmarked === true;
        }).reduce(function(list, threadRelation) {
          return list.concat(threads.filter(function(thread) {
            return thread.id === threadRelation.id;
          }));
        }, []);
      }

      您还可以创建地图,以提高查找性能。

      var threads = [
        { id: 1 },
        { id: 2 },
        { id: 3 }
      ];
      
      var users = [{
        user_id: 1,
        threadRelations: [
          { id: 2,  isBookmarked: true },
          { id: 18, isBookmarked: true }
        ]
      }];
      
      var threadMap           = mapBy(threads, 'id');
      var userBookmarkedList  = retrieveBookmarkedThreads(users[0], threadMap);
      document.body.innerHTML = '<pre>Threads -> ' + JSON.stringify(userBookmarkedList, null, 2) + '</pre>';
      
      function mapBy(list, key) {
        return list.reduce(function(map, item) {
          map[item[key]] = item;
          return map;
        }, {});
      }
      
      function retrieveBookmarkedThreads(user, threadMap) {
        return user.threadRelations.filter(function(threadRelation) {
          return threadRelation.isBookmarked === true;
        }).reduce(function(list, threadRelation) {
          return (function(thread) {
            return thread != null ? list.concat(thread) : list;
          }(threadMap[threadRelation.id]));
        }, []);
      }

      【讨论】:

        猜你喜欢
        • 2019-05-29
        • 2022-11-10
        • 2015-04-08
        相关资源
        最近更新 更多