আমি কীভাবে একটি কৌণিক ফিল্টার দিয়ে ডেটা গ্রুপ করব?


136

আমার কাছে খেলোয়াড়ের একটি তালিকা রয়েছে যা প্রতিটি গ্রুপের অন্তর্ভুক্ত। আমি প্রতি গ্রুপ হিসাবে ব্যবহারকারীদের তালিকা করতে একটি ফিল্টার কীভাবে ব্যবহার করতে পারি?

[{name: 'Gene', team: 'team alpha'},
 {name: 'George', team: 'team beta'},
 {name: 'Steve', team: 'team gamma'},
 {name: 'Paula', team: 'team beta'},
 {name: 'Scruath of the 5th sector', team: 'team gamma'}];

আমি এই ফলাফলটি খুঁজছি:

  • দল আলফা
    • জিন
  • দল বিটা
    • জর্জ
    • পলা
  • দল গামা
    • স্টিভ
    • 5 ম সেক্টরের স্ক্রুথ

উত্তর:


182

আপনি কৌণিক.ফিল্টার মডিউলের গ্রুপবাই ব্যবহার করতে পারেন ।
সুতরাং আপনি এই জাতীয় কিছু করতে পারেন:

জাতীয়:

$scope.players = [
  {name: 'Gene', team: 'alpha'},
  {name: 'George', team: 'beta'},
  {name: 'Steve', team: 'gamma'},
  {name: 'Paula', team: 'beta'},
  {name: 'Scruath', team: 'gamma'}
];

এইচটিএমএল:

<ul ng-repeat="(key, value) in players | groupBy: 'team'">
  Group name: {{ key }}
  <li ng-repeat="player in value">
    player: {{ player.name }} 
  </li>
</ul>

ফলাফল:
গ্রুপের নাম: আলফা
* প্লেয়ার: জিন
গ্রুপের নাম: বিটা
* প্লেয়ার: জর্জ
* প্লেয়ার: পলা
গ্রুপের নাম: গামা
* প্লেয়ার: স্টিভ
* প্লেয়ার: স্ক্রোয়াথ

আপডেট: jsbin ব্যবহারের প্রাথমিক প্রয়োজনীয়তাগুলি মনে রাখবেন angular.filter, বিশেষভাবে নোট করুন আপনার এটি অবশ্যই আপনার মডিউলের নির্ভরতাতে যুক্ত করতে হবে:

(1) আপনি 4 টি বিভিন্ন পদ্ধতি ব্যবহার করে কৌণিক-ফিল্টার ইনস্টল করতে পারেন:

  1. ক্লোন করুন এবং এই সংগ্রহস্থল নির্মাণ করুন
  2. বাওয়ারের মাধ্যমে: চালিয়ে $ বোর আপনার টার্মিনাল থেকে কৌনিক-ফিল্টার ইনস্টল করুন
  3. এনপিএমের মাধ্যমে: আপনার টার্মিনাল থেকে $ npm ইনস্টল করুন কৌণিক-ফিল্টার ইনস্টল করুন
  4. সিডিএনজেএস এর মাধ্যমে http://www.cdnjs.com/libraries/angular-filter

(২) কৌণিক নিজেই অন্তর্ভুক্ত করার পরে আপনার সূচক html এ কৌণিক-ফিল্টার.জেএস (বা কৌণিক-ফিল্টার.মিন.জেএস) অন্তর্ভুক্ত করুন।

(3) আপনার মূল মডিউলটির নির্ভরতার তালিকায় 'অ্যাঙ্গুলার.ফিল্টার' যুক্ত করুন।


দুর্দান্ত উদাহরণ। তবে কীটি গ্রুপটির নাম দেয় এবং আসল কীটি দেয় না ... আমরা কীভাবে এটি সমাধান করতে পারি?
অ্যান্ড্রুজ

7
angular.filterমডিউলটি অন্তর্ভুক্ত করতে ভুলবেন না ।
পুস

1
আপনি গ্রুপ-বাই @ স্পিলিং, পিটিএল দিয়ে অর্ডার-বায়ু ব্যবহার করতে পারেন: github.com/a8m/angular-filter/wiki/…
a8m

1
কি শান্তি. ধন্যবাদ। নেস্টেড লুপটি বাইরেরটিকে সেইভাবে প্রভাবিত করার জন্য অর্ডার করার আশা করিনি। এটা সত্যিই দরকারী। +1
erfling

1
@ জাইরয়েড এমনকি আমি যা খুঁজছি ঠিক সেটিকেই আমি অনুসন্ধান করতে চাই key। আপনার পক্ষ থেকে কোনও ভাগ্য
দুর্দান্ত শীতল

25

উপরে গৃহীত উত্তরগুলি ছাড়াও আমি আন্ডারস্কোর.জেএস লাইব্রেরি ব্যবহার করে একটি জেনেরিক 'গ্রুপ বাই' ফিল্টার তৈরি করেছি।

জেএসফিডেল (আপডেট হয়েছে): http://jsfiddle.net/TD7t3/

ফিল্টার

app.filter('groupBy', function() {
    return _.memoize(function(items, field) {
            return _.groupBy(items, field);
        }
    );
});

'স্মৃতিচারণ' কলটি নোট করুন। এই আন্ডারস্কোর পদ্ধতিটি ফাংশনটির ফলাফলকে ক্যাশে করে এবং প্রতিবার ফিল্টার এক্সপ্রেশনটি মূল্যায়ন থেকে কৌণিক থামায়, এইভাবে কৌণিকটি ডাইজেস্ট পুনরাবৃত্তির সীমাতে পৌঁছাতে বাধা দেয়।

এইচটিএমএল

<ul>
    <li ng-repeat="(team, players) in teamPlayers | groupBy:'team'">
        {{team}}
        <ul>
            <li ng-repeat="player in players">
                {{player.name}}
            </li>
        </ul>
    </li>
</ul>

আমরা টিমপ্লেয়ার স্কোপ ভেরিয়েবল, 'টিম' সম্পত্তিতে আমাদের 'গ্রুপবাই' ফিল্টার প্রয়োগ করি। আমাদের এনজি-রিপিট (কী, মানগুলি []) এর সংমিশ্রণটি গ্রহণ করে যা আমরা আমাদের নিম্নলিখিত পুনরাবৃত্তিতে ব্যবহার করতে পারি।

11 ই জুন আপডেট করুন 2014 আমি কী হিসাবে অভিব্যক্তির ব্যবহারের জন্য অ্যাকাউন্টটি ফিল্টার করে গ্রুপটি প্রসারিত করেছি (যেমন নেস্টেড ভেরিয়েবল)) কৌণিক পার্স পরিষেবাটি এর জন্য বেশ কাজে আসে:

ফিল্টার (এক্সপ্রেশন সমর্থন সহ)

app.filter('groupBy', function($parse) {
    return _.memoize(function(items, field) {
        var getter = $parse(field);
        return _.groupBy(items, function(item) {
            return getter(item);
        });
    });
});

নিয়ামক (নেস্টেড বস্তু সহ)

app.controller('homeCtrl', function($scope) {
    var teamAlpha = {name: 'team alpha'};
    var teamBeta = {name: 'team beta'};
    var teamGamma = {name: 'team gamma'};

    $scope.teamPlayers = [{name: 'Gene', team: teamAlpha},
                      {name: 'George', team: teamBeta},
                      {name: 'Steve', team: teamGamma},
                      {name: 'Paula', team: teamBeta},
                      {name: 'Scruath of the 5th sector', team: teamGamma}];
});

এইচটিএমএল (সাজ্ট বাই এক্সপ্রেশন সহ)

<li ng-repeat="(team, players) in teamPlayers | groupBy:'team.name'">
    {{team}}
    <ul>
        <li ng-repeat="player in players">
            {{player.name}}
        </li>
    </ul>
</li>

জেএসফিডাল: http://jsfiddle.net/k7fgB/2/


আপনি ঠিক বলেছেন, ফিডাল লিঙ্কটি আপডেট করা হয়েছে। আমাকে জানানোর জন্য আপনাকে ধন্যবাদ।
খ্রিস্ট

3
এটি আসলে বেশ ঝরঝরে! স্বল্প পরিমাণের কোড।
বেনি বোটেমা

3
এটির সাথে একটি বিষয় লক্ষণীয় - ডিফল্টরূপে মেমোয়েজ প্রথম প্যারাম (অর্থাত্ 'আইটেম') কে ক্যাচি কী হিসাবে ব্যবহার করে - তাই আপনি যদি এটি 'আইটেম' আলাদা আলাদা 'ক্ষেত্রের' দিয়ে পাস করেন তবে এটি একই ক্যাশেড মানটি ফিরে আসবে। সমাধান স্বাগত জানাই।
টম কারভার

আমি মনে করি আপনি এটি পেতে $ আইডি মানটি ব্যবহার করতে পারেন: আইটেমের আইটেমটি $ আইডি (আইটেম) দ্বারা ট্র্যাক করুন
ক্যাস্পার হারমার

2
কোন "গৃহীত উত্তর"? স্ট্যাক ওভারফ্লোতে, কেবলমাত্র একটি গ্রহণযোগ্য উত্তর থাকতে পারে।
সেবাস্তিয়ান মাচ

19

প্রথমে একটি ফিল্টার ব্যবহার করে একটি লুপ করুন যা কেবলমাত্র অনন্য দলগুলিতে ফিরে আসবে এবং তারপরে একটি নেস্টেড লুপ যা বর্তমান দলের প্রতি সমস্ত খেলোয়াড়কে ফিরিয়ে দেয়:

http://jsfiddle.net/plantface/L6cQN/

এইচটিএমএল:

<div ng-app ng-controller="Main">
    <div ng-repeat="playerPerTeam in playersToFilter() | filter:filterTeams">
        <b>{{playerPerTeam.team}}</b>
        <li ng-repeat="player in players | filter:{team: playerPerTeam.team}">{{player.name}}</li>        
    </div>
</div>

লিপি:

function Main($scope) {
    $scope.players = [{name: 'Gene', team: 'team alpha'},
                    {name: 'George', team: 'team beta'},
                    {name: 'Steve', team: 'team gamma'},
                    {name: 'Paula', team: 'team beta'},
                    {name: 'Scruath of the 5th sector', team: 'team gamma'}];

    var indexedTeams = [];

    // this will reset the list of indexed teams each time the list is rendered again
    $scope.playersToFilter = function() {
        indexedTeams = [];
        return $scope.players;
    }

    $scope.filterTeams = function(player) {
        var teamIsNew = indexedTeams.indexOf(player.team) == -1;
        if (teamIsNew) {
            indexedTeams.push(player.team);
        }
        return teamIsNew;
    }
}

খুবই সোজা. সুন্দর একটি @ প্ল্যান্টফেস।
জেফ ইয়েটস

শুধু উজ্জ্বল . তবে আমি যদি ক্লিক করে কোনও নতুন অবজেক্ট-স্কোপ.প্লেয়ারগুলিতে ঠেলে দিতে চাই তবে কী হবে? আপনি একটি ফাংশন মাধ্যমে লুপিং হিসাবে এটি যুক্ত করা হবে?
সুপার শীতল

16

আমি মূলত প্ল্যান্টফেসের উত্তরটি ব্যবহার করেছি, তবে সিনট্যাক্সটি কীভাবে আমার দৃষ্টিতে দেখায় তা পছন্দ করি না।

আমি এটি পুনরায় কাজ করেছিলাম। Q.de ব্যবহার করে ডেটা পোস্ট-প্রসেস এবং অনন্য দলগুলিতে একটি তালিকা ফিরিয়ে দেব , যা ফিল্টার হিসাবে ব্যবহৃত হয়।

http://plnkr.co/edit/waWv1donzEMdsNMlMHBa?p=preview

দৃশ্য

<ul>
  <li ng-repeat="team in teams">{{team}}
    <ul>
      <li ng-repeat="player in players | filter: {team: team}">{{player.name}}</li> 
    </ul>
  </li>
</ul>

নিয়ামক

app.controller('MainCtrl', function($scope, $q) {

  $scope.players = []; // omitted from SO for brevity

  // create a deferred object to be resolved later
  var teamsDeferred = $q.defer();

  // return a promise. The promise says, "I promise that I'll give you your
  // data as soon as I have it (which is when I am resolved)".
  $scope.teams = teamsDeferred.promise;

  // create a list of unique teams. unique() definition omitted from SO for brevity
  var uniqueTeams = unique($scope.players, 'team');

  // resolve the deferred object with the unique teams
  // this will trigger an update on the view
  teamsDeferred.resolve(uniqueTeams);

});

1
এই উত্তরটি AngularJS> 1.1 এর সাথে কাজ করছে না কারণ প্রতিশ্রুতি দেওয়া হয়েছে অ্যারেগুলির জন্য আর মোড়ানো হয় না। দেখুন অভিবাসন নোট
বেনি Bottema

6
এই সমাধানে প্রতিশ্রুতির কোনও দরকার নেই, কারণ আপনি অবিচ্ছিন্নভাবে কিছু করছেন না। এই ক্ষেত্রে, আপনি কেবল সেই পদক্ষেপটি ছেড়ে যেতে পারেন ( জেএসফিডাল )।
বেনি বোটেমা

11

উভয় উত্তর ভাল ছিল তাই আমি এগুলিকে একটি নির্দেশিকায় সরিয়ে নিয়েছি যাতে এটি পুনরায় ব্যবহারযোগ্য এবং দ্বিতীয় স্কোপ ভেরিয়েবল সংজ্ঞায়িত করতে না হয়।

এখানে বেহালার হয় যদি আপনি এটি বাস্তবায়িত দেখতে চাই

নীচে নির্দেশনাটি দেওয়া হল:

var uniqueItems = function (data, key) {
    var result = [];
    for (var i = 0; i < data.length; i++) {
        var value = data[i][key];
        if (result.indexOf(value) == -1) {
            result.push(value);
        }
    }
    return result;
};

myApp.filter('groupBy',
            function () {
                return function (collection, key) {
                    if (collection === null) return;
                    return uniqueItems(collection, key);
        };
    });

তারপরে এটি নিম্নলিখিত হিসাবে ব্যবহার করা যেতে পারে:

<div ng-repeat="team in players|groupBy:'team'">
    <b>{{team}}</b>
    <li ng-repeat="player in players | filter: {team: team}">{{player.name}}</li>        
</div>

11

হালনাগাদ

আমি প্রথমে এই উত্তরটি লিখেছেন কারণ সমাধান এরিয়েল এম দ্বারা প্রস্তাবিত পুরোনো সংস্করণ যখন অপরের সাথে মিলিত $filterগুলি একটি আলোড়ন সৃষ্টি " Infite $ diggest লুপ ত্রুটি " ( infdig) । ভাগ্যক্রমে এই সমস্যাটি অ্যাঙ্গুলার.ফিল্টারের সর্বশেষ সংস্করণে সমাধান করা হয়েছে ।

আমি নিম্নলিখিত প্রয়োগের পরামর্শ দিয়েছি, এতে সমস্যা নেই :

angular.module("sbrpr.filters", [])
.filter('groupBy', function () {
  var results={};
    return function (data, key) {
        if (!(data && key)) return;
        var result;
        if(!this.$id){
            result={};
        }else{
            var scopeId = this.$id;
            if(!results[scopeId]){
                results[scopeId]={};
                this.$on("$destroy", function() {
                    delete results[scopeId];
                });
            }
            result = results[scopeId];
        }

        for(var groupKey in result)
          result[groupKey].splice(0,result[groupKey].length);

        for (var i=0; i<data.length; i++) {
            if (!result[data[i][key]])
                result[data[i][key]]=[];
            result[data[i][key]].push(data[i]);
        }

        var keys = Object.keys(result);
        for(var k=0; k<keys.length; k++){
          if(result[keys[k]].length===0)
            delete result[keys[k]];
        }
        return result;
    };
});

যাইহোক, এই বাস্তবায়নটি কেবল কৌনিক 1.3 এর পূর্বে সংস্করণগুলির সাথে কাজ করবে। (আমি শীঘ্রই এই উত্তরটি আপডেট করব যা একটি সমাধান সরবরাহ করে যা সমস্ত সংস্করণে কাজ করে)

আমি এটি বিকাশের জন্য যে পদক্ষেপ নিয়েছি $filter, যে সমস্যাগুলির মুখোমুখি হয়েছিলাম এবং সেগুলি থেকে আমি কী শিখেছি সে সম্পর্কে আমি আসলে একটি পোস্ট লিখেছিলাম


হাই @ জোসেপ, নতুন angular-filterসংস্করণটি দেখুন - ০.০.০, এর ব্যতিক্রম আর নেই। groupByযে কোনও ফিল্টার দিয়ে চেইন হতে পারে। এছাড়াও, আপনি দুর্দান্ত পরীক্ষার কেস সাফল্যের সাথে শেষ করেছেন - এখানে একটি নিমজ্জনকারী ধন্যবাদ।
এম

1
@ জোসেপ কৌণিক 1.3
amcdnl

2

আপনি একাধিক কলাম দ্বারা দলবদ্ধ করতে চাইলে গ্রহণযোগ্য উত্তর ছাড়াও আপনি এটি ব্যবহার করতে পারেন :

<ul ng-repeat="(key, value) in players | groupBy: '[team,name]'">

0

আপনার যদি প্রয়োজন হয় তবে জেএস কোডে। আপনি অ্যাঙ্গুলা-ফিল্টার lib এর ইনজেকশন পদ্ধতি ব্যবহার করতে পারেন। এটার মত.

function controller($scope, $http, groupByFilter) {     

   var groupedData = groupByFilter(originalArray, 'groupPropName');

}

https://github.com/a8m/angular-filter/wiki/Common-Questions#inject-filters

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.