Возвращаемый массив JS на основе сравнения двух массивов с вложенными элементами

0

Использование Angular и попытка вернуть результат, основанный на сравнении двух массивов. Вот что я имею:

$scope.fbFriends = [{"id":1234,"name":'bob'},
                    {"id":4567,"name":'john'}, 
                    {"id":8910,"name":'totoro'}];
$scope.appFriends = [{"id":1,"name":'bob',"fb_id":1234},          
                     {"id":2,"name":'john',"fb_id":4567}];

Я хотел бы отфильтровать друзей, которые существуют в обоих, и возвращать только те из fbFriends, которых нет в appFriends. Это то, что я сделал, но он не работает, он возвращает слишком много раз.

$scope.not_friends = [];
        $scope.filtered = [];
        for (var i=0; i < $scope.fbFriends.length; i++) {
           for (var j=0; j < $scope.appFriends.length; j++) {
             if ($scope.fbFriends[i].id !== $scope.appFriends[j].fb_id) {
               $scope.not_friends = $scope.fbFriends[i];
               $scope.filtered.push($scope.not_friends);
             }
           }
        };
        console.log($scope.filtered);

Что не так в этом подходе? Бонус, можно ли интегрировать это в фильтр и использовать его в ng-повторе fbFriends?

Благодарю!!

Теги:
arrays
filter

2 ответа

0

Здесь общая операция разностного набора

difference = function(a, b, eq) {
  return a.filter(function(x) {
    return b.every(function(y) {
      return !eq(x, y)
    });
  });
}

где a, b - массивы, eq - функция равенства.

И вот как применить его к вашей проблеме:

fbFriends = [{"id":1234,"name":'bob'},
                    {"id":4567,"name":'john'}, 
                    {"id":8910,"name":'totoro'}];
appFriends = [{"id":1,"name":'bob',"fb_id":1234},          
                     {"id":2,"name":'john',"fb_id":4567}];


difference = function(a, b, eq) {
  return a.filter(function(x) {
    return b.every(function(y) {
      return !eq(x, y)
    });
  });
}

onlyFb = difference(fbFriends, appFriends, function(f, a) {
  return f.id === a.fb_id
});

document.write(JSON.stringify(onlyFb))
  • 0
    это выглядит действительно хорошо! Позвольте мне попытаться реализовать это! Как вы думаете, я мог бы взять разностную функцию из моего контроллера и создать из нее фильтр?
0

Проблема в if block: вы должны проверить равенство, а затем - поскольку вы ищете друзей, которые НЕ содержатся в fbFriends - удалите объект.

Я переписал ваш код и, похоже, работает правильно.

$scope.fbFriends = [{"id":1234,"name":'bob'},
        {"id":4567,"name":'john'},
        {"id":8910,"name":'totoro'}];
      $scope.appFriends = [{"id":1,"name":'bob',"fb_id":1234},
        {"id":2,"name":'john',"fb_id":4567}];

      for (var i=0; i < $scope.appFriends.length; i++) {
        // we parse the 'reference array'
        for (var j=0; j < $scope.fbFriends.length; j++) {
          // we check every value inside the 'container array'
          if ($scope.fbFriends[j].id == $scope.appFriends[i].fb_id) {

            // the element is alredy inside the appFriends

            $scope.fbFriends.splice(j,1);
          }
        }
      }

      console.log($scope.fbFriends);

Дальнейшую ссылку см. В книге алгоритмов ("Предложение о шахте" - введение в алгоритмы Томаса Х. Кормена, но кто-то это сделает).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню