javascript 从 Angular JS ng-options / ng-repeat 中删除重复项

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23595034/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 01:11:09  来源:igfitidea点击:

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

javascriptangularjs

提问by vimes1984

I have the following:

我有以下几点:

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

And this in my html:

这在我的 html 中:

<select id="typeselect"  multiple  ng-options="accnts.type for accnts in jsonmarkers" ng-model="accnt" ng-change="changeaccnt(accnt.type)"></select>

How do I go about matching the type and only echoing it once per appearance in the ng-options?

我如何去匹配类型,并且每次出现只回显一次ng-options

回答by Nidhish Krishnan

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

要删除重复项,您可以使用AngularUI 中的唯一过滤器(此处提供源代码:AngularUI unique filter)并直接在 ng-options(或 ng-repeat)中使用它。

Look here for more: Unique & Stuff

在此处查看更多信息:Unique & Stuff

Also there's a syntax error in json structure.

json 结构中也存在语法错误。

Working Code

工作代码

Html

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;
    };
});

回答by Fido488

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

我修改了 NidhishKrishnan 给出的答案,以使答案适用于嵌套对象。

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.

您将看到一个列表,其中仅显示培训选项。