Removing duplicates from Angular JS ng-options / ng-repeat

前端 未结 2 1811
心在旅途
心在旅途 2020-12-11 22:40

I have the following:

$scope.jsonmarkers = [{
    \"name\": \"Jeff\",
        \"type\": \"Organisation + Training Entity\",
        \"userID\": \"1\"
}, {
          


        
相关标签:
2条回答
  • 2020-12-11 23:14

    For removing duplicates you could use the unique filter from AngularUI (source code available here: AngularUI unique filter) and use it directly in the ng-options (or ng-repeat).

    Look here for more: Unique & Stuff

    Also there's a syntax error in json structure.

    Working Code

    Html

    <div ng-app="app">
        <div ng-controller="MainController">
            <select id="typeselect"  ng-options="accnts.type for accnts in jsonmarkers | unique:'type'" ng-model="accnt" ng-change="changeaccnt(accnt.type)" multiple></select>
        </div>
    </div>
    

    script

        var app = angular.module("app", []);
    
    app.controller("MainController", function ($scope) {
        $scope.jsonmarkers = [{
            "name": "Jeff",
                "type": "Organisation + Training Entity",
                "userID": "1"
        }, {
            "name": "Fred",
                "type": "Organisation + Training Entity",
                "userID": "2"
        }];
    });
    
    
    app.filter('unique', function () {
    
        return function (items, filterOn) {
    
            if (filterOn === false) {
                return items;
            }
    
            if ((filterOn || angular.isUndefined(filterOn)) && angular.isArray(items)) {
                var hashCheck = {}, newItems = [];
    
                var extractValueToCompare = function (item) {
                    if (angular.isObject(item) && angular.isString(filterOn)) {
                        return item[filterOn];
                    } else {
                        return item;
                    }
                };
    
                angular.forEach(items, function (item) {
                    var valueToCheck, isDuplicate = false;
    
                    for (var i = 0; i < newItems.length; i++) {
                        if (angular.equals(extractValueToCompare(newItems[i]), extractValueToCompare(item))) {
                            isDuplicate = true;
                            break;
                        }
                    }
                    if (!isDuplicate) {
                        newItems.push(item);
                    }
    
                });
                items = newItems;
            }
            return items;
        };
    });
    
    0 讨论(0)
  • 2020-12-11 23:24

    I modified the answer that NidhishKrishnan gave in order to make the answer work for nested objects.

    For example if you have:

    $scope.jsonmarkers = [{
        "name": "Jeff",
        "type": "Organisation + Training Entity",
        "userID": "1",
        "userData": {
            "hire reason":"training"
        }
    }, {
        "name": "Fred",
        "type": "Organisation + Training Entity",
        "userID": "2"
        "userData": {
            "hire reason":"training"
        }
    }];
    

    This is the modified version:

    angular.module('ArtifactFeederApp.filters', [])
    
        .filter('unique', function () {
        return function (items, filterOn) {
    
            if (filterOn === false) {
                return items;
            }
    
            if ((filterOn || angular.isUndefined(filterOn)) && angular.isArray(items)) {
                var hashCheck = {}, newItems = [];
    
                var extractValueToCompare = function (item) {
                    if (angular.isObject(item) && angular.isString(filterOn)) {
    
                        var resolveSearch = function(object, keyString){
                            if(typeof object == 'undefined'){
                                return object;
                            }
                            var values = keyString.split(".");
                            var firstValue = values[0];
                            keyString = keyString.replace(firstValue + ".", "");
                            if(values.length > 1){
                                return resolveSearch(object[firstValue], keyString);
                            } else {
                                return object[firstValue];
                            }
                        }
    
                        return resolveSearch(item, filterOn);
                    } else {
                        return item;
                    }
                };
    
                angular.forEach(items, function (item) {
                    var valueToCheck, isDuplicate = false;
    
                    for (var i = 0; i < newItems.length; i++) {
                        if (angular.equals(extractValueToCompare(newItems[i]), extractValueToCompare(item))) {
                            isDuplicate = true;
                            break;
                        }
                    }
                    if (!isDuplicate) {
                        if(typeof item != 'undefined'){
                            newItems.push(item);
                        }
                    }
    
                });
                items = newItems;
            }
            return items;
        };
    });
    

    You can now do:

    <div ng-controller="MainController">
        <select id="typeselect"  ng-options="accnts.type for accnts in jsonmarkers | unique:'userData.hire reason'" ng-model="accnt" ng-change="changeaccnt(accnt.type)" multiple></select>
    </div>
    

    And you will see a list that only shows training as an option.

    0 讨论(0)
提交回复
热议问题