0

I have this algorithme issue, I would like to check if an Object is already present in my Array before adding it.

I tried many different approaches (indexOf, filter...), and my last attempt is with an angular.foreach.

The problem is my $scope.newJoin remains always empty. I understood why, it's because the if is never read, because of the 0 size of my $scope.newJoin, but I don't know how to figure this out...


$scope.newJoinTMP is composed by : 6 Objects, within each a timePosted attribute (used for compare these different array Objects).

$scope.newJoin is an empty Array. I want to fill it with the Objects inside $scope.newJoinTMP but with the certainty to have once each Objects, and not twice the same ($scope.newJoinTMP can have duplicates Objects inside, but $scope.newJoin mustn't).

                    angular.forEach($scope.newJoinTMP, function(item) 
                    { 
                       
                        angular.forEach($scope.newJoin, function(item2)
                        {
                            if (item.timePosted === item2.timePosted) 
                            {
                                //snap.val().splice(snap.val().pop(item));
                                console.log("pop");
                            }
                            else
                            {
                                $scope.newJoin.push(item);
                                console.log("newJoin :", $scope.newJoin);
                            }
                        });
                    });

4 Answers 4

1
if(!$scope.newJoin.find(el=>item.timePosted===el.timePosted){      
      $scope.newJoin.push(item);
      console.log("newJoin :", $scope.newJoin);
}

You dont want to push inside an forEach, as it will push multiple times...

Sign up to request clarification or add additional context in comments.

2 Comments

Oooh that is a mistake I always done, thank you to pointed it...How to replace a push inside a forEach ? With a simple index value that I increment in each loop ? Like so : $scope.newJoin[i] = item ?
@memphis: have a look at my code again ( it already contains an answer ;))
1

There might be better ways to handle your particular situation but here's a fix for your particular code. Replaced your inner for each with some which returns boolean for the presence of element and by that boolean value, deciding whether to add element or not

                angular.forEach($scope.newJoinTMP, function(item) 
                { 

                    var isItemPresent = $scope.newJoin.some(function(item2)
                    {
                        return item.timePosted === item2.timePosted;
                        //you dont need this conditional handling for each iteration.
                       /* if (item.timePosted === item2.timePosted) 
                        {
                            //snap.val().splice(snap.val().pop(item));
                            console.log("pop");
                        }
                        else
                        {
                            $scope.newJoin.push(item);
                            console.log("newJoin :", $scope.newJoin);
                        } */
                    });
                    if( ! isItemPresent ) {
                       $scope.newJoin.push(item);
                    } else {
                       //do if it was present.
                    }
                });

Comments

1

If you want to avoid the nested loop (forEach, some, indexOf, or whatever) you can use an auxiliar object. It will use more memory but you will spent less time.

let arr = [{ id: 0 }, { id:0 }, { id: 1}];
let aux = {};

const result = arr.reduce((result, el) => {
  if (aux[el.id] === undefined) {
    aux[el.id] = null;
    return [el, ...result];
  } else {
    return result;
  }
}, []);

console.log(result);

Comments

0

You can use reduce

$scope.newJoin = $scope.newJoinTMP.reduce(function(c, o, i) {
    var contains = c.some(function(obj) {
        return obj.timePosted == o.timePosted;
    });

    if (!contains) {
        c.push(o);
    }

    return c;
}, []);

The problem with your current code is, if newJoin is empty, nothing will ever get added to it - and if it isnt empty, if the first iteration doesn't match the current item being iterated from newJoinTMP - you're pushing.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.