কীভাবে এনজি-রিপিট ফিল্টার তৈরি করতে হবে সদৃশ ফলাফল out


131

আমি ng-repeatএকটি JSON ফাইলের উপর একটি সহজ চালাচ্ছি এবং বিভাগের নাম পেতে চাই। এখানে প্রায় 100 টি অবজেক্ট রয়েছে, প্রত্যেকটি একটি বিভাগের অন্তর্গত - তবে এখানে প্রায় 6 টি বিভাগ রয়েছে।

আমার বর্তমান কোডটি হ'ল:

<select ng-model="orderProp" >
  <option ng-repeat="place in places" value="{{place.category}}">{{place.category}}</option>
</select>

আউটপুট 100 টি বিভিন্ন বিকল্প, বেশিরভাগ সদৃশ। {{place.category}}ইতিমধ্যে উপস্থিত রয়েছে কিনা তা যাচাই করার জন্য আমি কৌনিকটি কীভাবে ব্যবহার করব এবং এটি ইতিমধ্যে উপস্থিত থাকলে কোনও বিকল্প তৈরি করব না?

সম্পাদনা করুন: আমার জাভাস্ক্রিপ্টে $scope.places = JSON data, কেবল স্পষ্ট করার জন্য


1
কেন আপনি কেবল আপনার $ সুযোগ.প্লেসগুলি ছাড়বেন না? jquery মানচিত্র api.jquery.com/map
anazimok

আপনার চূড়ান্ত কাজের সমাধান কি ছিল? এটি কি এটি উপরে বা কোনও জেএস ডি-
ডুপিং

আমি এর সমাধান জানতে চাই। দয়া করে একটি ফলো-আপ পোস্ট করুন। ধন্যবাদ!
jdstein1

@ jdstein1 আমি একটি টিএলডিআর দিয়ে শুরু করব: নীচের উত্তরগুলি ব্যবহার করুন বা একটি অ্যারেতে কেবল অনন্য মানগুলি ফিল্টার করতে ভ্যানিলা জাভাস্ক্রিপ্ট ব্যবহার করুন। আমি যা করেছি: শেষ পর্যন্ত, এটি আমার যুক্তি এবং এমভিসি সম্পর্কে আমার বুঝতে সমস্যা ছিল। আমি মঙ্গোডিবি থেকে ডেটা লোড করার সময় ডেটা ফেলার জন্য জিজ্ঞাসা করছিলাম এবং অ্যাঙ্গুলারটি চাইছিল যাদুতে এটি কেবল অনন্য স্থানে ফিল্টার করে। সমাধান, যেমন প্রায়শই কেসটি ছিল, অলস হওয়া বন্ধ করা এবং আমার ডিবি মডেলটি ঠিক করা - আমার জন্য, এটি মঙ্গোর ডাকছিল db.collection.distinct("places"), যা অ্যাঙ্গুলারের মধ্যে করা থেকে অনেক বেশি ভাল ছিল! দুঃখজনকভাবে এটি সবার জন্য কাজ করবে না।
JVG

আপডেটের জন্য ধন্যবাদ!
jdstein1

উত্তর:


142

আপনি ব্যবহার করতে পারে অনন্য (উৎস এখানে পাওয়া যায় কোড: AngularUI থেকে ফিল্টার AngularUI অনন্য ফিল্টার ) এবং এটা সরাসরি ব্যবহার NG-বিকল্পগুলিতে (অথবা NG-পুনরাবৃত্তি)।

<select ng-model="orderProp" ng-options="place.category for place in places | unique:'category'">
    <option value="0">Default</option>
    // unique options from the categories
</select>

33
যারা AngularUI এর অনন্য ফিল্টারটি কাজ করতে পারে না তাদের জন্য: ফিল্টারগুলি আলাদা মডিউলে থাকে: যেমন আপনার মডিউলে এটি একটি অতিরিক্ত রেফারেন্স হিসাবে অবশ্যই অন্তর্ভুক্ত করতে হবে angular.module('yourModule', ['ui', 'ui.filters']);। আমি AngularUI js ফাইলের ভিতরে না যাওয়া পর্যন্ত স্টাম্পড হয়েছিল।
GFoley83

8
uniqueফিল্টার বর্তমানে অংশ হিসেবে পাওয়া যাবে AngularJs UI 'তে utils
নিক

2
ইউআই ব্যবহারের নতুন সংস্করণে, আপনি কেবল ui.unique এর নিজের থেকে অন্তর্ভুক্ত করতে পারেন। মাত্র মডিউলটির জন্য বওয়ার ইনস্টল ব্যবহার করুন।
পরিসংখ্যানগুলি শিখুন উদাহরণস্বরূপ

আপনি যদি AngularUI এবং এর সম্পূর্ণতা অন্তর্ভুক্ত না করতে চান তবে অনন্য ফিল্টারটি ব্যবহার করতে চান তবে আপনি অনন্য.জেএস উত্সটি আপনার অ্যাপ্লিকেশনটিতে অনুলিপি করতে পারেন, তারপরে angular.module('ui.filters')আপনার অ্যাপ্লিকেশানের নাম পরিবর্তন করুন।
চেকদা

37

অথবা আপনি লড্যাশ ব্যবহার করে নিজের ফিল্টার লিখতে পারেন।

app.filter('unique', function() {
    return function (arr, field) {
        return _.uniq(arr, function(a) { return a[field]; });
    };
});

হ্যালো মাইক, দেখতে সত্যিই মার্জিত দেখাচ্ছে তবে আমি যখন অনন্য মতো ফিল্টারটি পাস করি তখন প্রত্যাশার মতো কাজ করে না বলে মনে হয়: স্ট্যাটাস [আমার ফিল্ডের নাম] এটি উপলব্ধ সমস্ত অনন্য মূর্তির পছন্দসই তালিকার বিপরীতে প্রথম ফলাফলটি দেয় return কোন অনুমান কেন?
সিনসাইক

3
যদিও আমি আন্ডারস্কোর ব্যবহার করেছি, এই সমাধানটি কবজির মতো কাজ করেছে। ধন্যবাদ!
জন ব্ল্যাক

খুব মার্জিত সমাধান।
জেডি স্মিথ

1
লোডাশ আন্ডারস্কোরের কাঁটাচামচ। এটিতে আরও ভাল পারফরম্যান্স এবং আরও বেশি সুবিধা রয়েছে।
মাইক ওয়ার্ড

2
লোডাস ভি 4 - তে_.uniqBy(arr, field); নেস্টেড প্রোপার্টিগুলির জন্য কাজ করা উচিত
আইজভিড

30

আপনি কৌণিক.ফিল্টার মডিউলে 'অনন্য' (উপাধি: ইউনিক) ফিল্টারটি ব্যবহার করতে পারেন

ব্যবহার: colection | uniq: 'property'
আপনি নেস্টেড বৈশিষ্ট্যগুলি দ্বারাও ফিল্টার করতে পারেন: colection | uniq: 'property.nested_property'

আপনি যা করতে পারেন তা হ'ল ..

function MainController ($scope) {
 $scope.orders = [
  { id:1, customer: { name: 'foo', id: 10 } },
  { id:2, customer: { name: 'bar', id: 20 } },
  { id:3, customer: { name: 'foo', id: 10 } },
  { id:4, customer: { name: 'bar', id: 20 } },
  { id:5, customer: { name: 'baz', id: 30 } },
 ];
}

এইচটিএমএল: আমরা গ্রাহক আইডি দ্বারা ফিল্টার করি, অর্থাৎ সদৃশ গ্রাহকরা সরিয়ে ফেলি

<th>Customer list: </th>
<tr ng-repeat="order in orders | unique: 'customer.id'" >
   <td> {{ order.customer.name }} , {{ order.customer.id }} </td>
</tr>

ফলাফল
গ্রাহক তালিকা:
foo 10
বার 20
বাজ 30


আপনার উত্তরটি পছন্দ করুন, তবে এটি আমার সমস্যার সাথে অনুবাদ করতে বেশ সময় ব্যয় হচ্ছে। আপনি কীভাবে কোনও নেস্টেড তালিকা পরিচালনা করবেন। উদাহরণস্বরূপ, প্রতিটি ক্রমের জন্য আইটেমগুলির একটি তালিকা থাকা অর্ডারগুলির একটি তালিকা। আপনার উদাহরণে, প্রতি অর্ডারে আপনার একজন গ্রাহক রয়েছে। আমি সমস্ত অর্ডার জুড়ে আইটেমের একটি অনন্য তালিকা দেখতে চাই। বিন্দুটি বেলবোর করার জন্য নয়, তবে আপনি এটি ভাবতেও পারেন যে কোনও গ্রাহকের অনেক অর্ডার রয়েছে এবং অর্ডারে অনেক আইটেম রয়েছে। গ্রাহক অর্ডার করেছেন এমন সমস্ত পূর্ববর্তী আইটেম আমি কীভাবে প্রদর্শন করতে পারি? থটস?
গ্রেগ গ্রেটার

@ গ্রেগগ্রাটার আপনি কি আপনার সমস্যার সাথে মিল রেখে উদাহরণস্বরূপ বস্তু সরবরাহ করতে পারেন?
a8m

ধন্যবাদ @ অ্যারিল এম! এখানে ডেটার উদাহরণ রয়েছে:
গ্রেগ গ্রেটার

কৌনিকটির কোন সংস্করণের সাথে এটি সামঞ্জস্যপূর্ণ?
আইসট

15

এই কোডটি আমার পক্ষে কাজ করে।

app.filter('unique', function() {

  return function (arr, field) {
    var o = {}, i, l = arr.length, r = [];
    for(i=0; i<l;i+=1) {
      o[arr[i][field]] = arr[i];
    }
    for(i in o) {
      r.push(o[i]);
    }
    return r;
  };
})

এবং তারপর

var colors=$filter('unique')(items,"color");

2
L এর সংজ্ঞাটি l = আরর হওয়া উচিত! = অপরিবর্তিত? arr.length: 0 অন্যথায় angularjs একটি পার্সিং ত্রুটি যেহেতু
Gerrit

6

আপনি যদি বিভাগগুলি তালিকাভুক্ত করতে চান তবে আমার মনে হয় আপনার দৃষ্টিভঙ্গিটি স্পষ্টভাবে প্রকাশ করা উচিত।

<select ng-model="orderProp" >
  <option ng-repeat="category in categories"
          value="{{category}}">
    {{category}}
  </option>
</select>

নিয়ামক মধ্যে:

$scope.categories = $scope.places.reduce(function(sum, place) {
  if (sum.indexOf( place.category ) < 0) sum.push( place.category );
  return sum;
}, []);

আপনি এই আরও কিছুটা ব্যাখ্যা করতে পারেন আমি প্রতিটি অনন্য বিভাগের জন্য এক সারি সারিতে উপাদানগুলি পুনরাবৃত্তি করতে চাই। জেএস কি ঠিক জেএস ফাইলটিতে যায় যেখানে নিয়ামক সংজ্ঞায়িত হয়?
1234

আপনি যদি বিকল্পগুলি গোষ্ঠী করতে চান তবে এটি আলাদা প্রশ্ন। আপনি অপ্টগ্রুপ উপাদানটি দেখতে চাইতে পারেন। কৌণিক অপ্টগ্রুপকে সমর্থন করে। নির্দেশে group byঅভিব্যক্তি অনুসন্ধান করুন select
তোশ

যে ক্ষেত্রে কোনও স্থান যুক্ত / সরানো হয়েছে সে ক্ষেত্রে কি ঘটবে? এটি সম্পর্কিত জায়গাগুলি যদি একমাত্র দৃষ্টান্ত হয় তবে কি সম্পর্কিত বিভাগটি যুক্ত / সরানো হবে?
গ্রেগ গ্রেটার

4

এখানে একটি সরল এবং জেনেরিক উদাহরণ।

ফিল্টার:

sampleApp.filter('unique', function() {

  // Take in the collection and which field
  //   should be unique
  // We assume an array of objects here
  // NOTE: We are skipping any object which
  //   contains a duplicated value for that
  //   particular key.  Make sure this is what
  //   you want!
  return function (arr, targetField) {

    var values = [],
        i, 
        unique,
        l = arr.length, 
        results = [],
        obj;

    // Iterate over all objects in the array
    // and collect all unique values
    for( i = 0; i < arr.length; i++ ) {

      obj = arr[i];

      // check for uniqueness
      unique = true;
      for( v = 0; v < values.length; v++ ){
        if( obj[targetField] == values[v] ){
          unique = false;
        }
      }

      // If this is indeed unique, add its
      //   value to our values and push
      //   it onto the returned array
      if( unique ){
        values.push( obj[targetField] );
        results.push( obj );
      }

    }
    return results;
  };
})

মার্কআপ:

<div ng-repeat = "item in items | unique:'name'">
  {{ item.name }}
</div>
<script src="your/filters.js"></script>

এটি দুর্দান্ত কাজ করে তবে এটি Cannot read property 'length' of undefinedলাইনে কনসোলে একটি ত্রুটি ছুড়ে l = arr.length
ফেলেছে

4

আমি অনন্য সদস্যের জন্য কোনও গভীরতার অনুমতি দেওয়ার জন্য @ থথকুরির উত্তরটি প্রসারিত করার সিদ্ধান্ত নিয়েছি। এখানে কোড। এটি কেবল তাদের কার্যকারিতার জন্য যারা পুরো AngularUI মডিউলটি অন্তর্ভুক্ত করতে চান না তাদের জন্য এটি। আপনি যদি ইতিমধ্যে AngularUI ব্যবহার করে থাকেন তবে এই উত্তরটিকে উপেক্ষা করুন:

app.filter('unique', function() {
    return function(collection, primaryKey) { //no need for secondary key
      var output = [], 
          keys = [];
          var splitKeys = primaryKey.split('.'); //split by period


      angular.forEach(collection, function(item) {
            var key = {};
            angular.copy(item, key);
            for(var i=0; i<splitKeys.length; i++){
                key = key[splitKeys[i]];    //the beauty of loosely typed js :)
            }

            if(keys.indexOf(key) === -1) {
              keys.push(key);
              output.push(item);
            }
      });

      return output;
    };
});

উদাহরণ

<div ng-repeat="item in items | unique : 'subitem.subitem.subitem.value'"></div>

2

আমার কাছে স্ট্রিংগুলির একটি অ্যারে ছিল, বস্তুগুলি নয় এবং আমি এই পদ্ধতিটি ব্যবহার করেছি:

ng-repeat="name in names | unique"

এই ফিল্টার সহ:

angular.module('app').filter('unique', unique);
function unique(){
return function(arry){
        Array.prototype.getUnique = function(){
        var u = {}, a = [];
        for(var i = 0, l = this.length; i < l; ++i){
           if(u.hasOwnProperty(this[i])) {
              continue;
           }
           a.push(this[i]);
           u[this[i]] = 1;
        }
        return a;
    };
    if(arry === undefined || arry.length === 0){
          return '';
    }
    else {
         return arry.getUnique(); 
    }

  };
}

2

হালনাগাদ

আমি সেটটির ব্যবহার পুনরুদ্ধার করছিলাম তবে দুঃখিত, এটি এনজি-পুনরাবৃত্তির জন্য কাজ করে না, যেহেতু এনজি-রিপিট কেবল অ্যারের সাথে কাজ করে না। সুতরাং এই উত্তর উপেক্ষা করুন। ওয়ান ওয়ে কোন পথে আপনি সদৃশ ফিল্টার করার জন্য প্রয়োজন অন্যান্য হিসেবে ব্যবহার কথা বলেন angular filters, এখানে শুরু বিভাগে এটা জন্য লিঙ্ক


পুরানো উত্তর

আপনি ECMAScript 2015 (ES6) স্ট্যান্ডার্ড সেট ডেটা স্ট্রাকচারটি অ্যারে ডেটা স্ট্রাকচারের পরিবর্তে এইভাবে সেটটিতে যুক্ত করার পরে পুনরাবৃত্তি মানগুলি ফিল্টার করতে পারবেন। (মনে রাখবেন সেটগুলি পুনরাবৃত্ত মানগুলিকে অনুমতি দেয় না)। ব্যবহার করা সত্যই সহজ:

var mySet = new Set();

mySet.add(1);
mySet.add(5);
mySet.add("some text");
var o = {a: 1, b: 2};
mySet.add(o);

mySet.has(1); // true
mySet.has(3); // false, 3 has not been added to the set
mySet.has(5);              // true
mySet.has(Math.sqrt(25));  // true
mySet.has("Some Text".toLowerCase()); // true
mySet.has(o); // true

mySet.size; // 4

mySet.delete(5); // removes 5 from the set
mySet.has(5);    // false, 5 has been removed

mySet.size; // 3, we just removed one value

2

এটি করার একমাত্র টেমপ্লেট উপায় (যদিও এটি অর্ডার বজায় রাখছে না)। এছাড়াও, ফলাফলটিও আদেশ করা হবে, যা বেশিরভাগ ক্ষেত্রে কার্যকর:

<select ng-model="orderProp" >
   <option ng-repeat="place in places | orderBy:'category' as sortedPlaces" data-ng-if="sortedPlaces[$index-1].category != place.category" value="{{place.category}}">
      {{place.category}}
   </option>
</select>

2

উপরের ফিল্টারগুলির মধ্যে কোনওটিই আমার সমস্যার সমাধান করেনি তাই আমাকে অফিসিয়াল গিথুব ডক থেকে ফিল্টারটি অনুলিপি করতে হয়েছিল এবং তারপরে উপরের উত্তরে বর্ণিত হিসাবে এটি ব্যবহার করুন

angular.module('yourAppNameHere').filter('unique', function () {

রিটার্ন ফাংশন (আইটেম, ফিল্টারআন) {

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

});

1

দেখে মনে হচ্ছে প্রত্যেকে uniqueফিল্টারটির নিজস্ব সংস্করণটি রিংয়ের মধ্যে ফেলে দিচ্ছে , তাই আমিও এটি করব। সমালোচনা খুব স্বাগত।

angular.module('myFilters', [])
  .filter('unique', function () {
    return function (items, attr) {
      var seen = {};
      return items.filter(function (item) {
        return (angular.isUndefined(attr) || !item.hasOwnProperty(attr))
          ? true
          : seen[item[attr]] = !seen[item[attr]];
      });
    };
  });

1

যদি আপনি নেস্টেড কীটির উপর ভিত্তি করে অনন্য ডেটা পেতে চান:

app.filter('unique', function() {
        return function(collection, primaryKey, secondaryKey) { //optional secondary key
          var output = [], 
              keys = [];

          angular.forEach(collection, function(item) {
                var key;
                secondaryKey === undefined ? key = item[primaryKey] : key = item[primaryKey][secondaryKey];

                if(keys.indexOf(key) === -1) {
                  keys.push(key);
                  output.push(item);
                }
          });

          return output;
        };
    });

এটিকে কল করুন:

<div ng-repeat="notify in notifications | unique: 'firstlevel':'secondlevel'">

0

এই ফিল্টার যুক্ত করুন:

app.filter('unique', function () {
return function ( collection, keyname) {
var output = [],
    keys = []
    found = [];

if (!keyname) {

    angular.forEach(collection, function (row) {
        var is_found = false;
        angular.forEach(found, function (foundRow) {

            if (foundRow == row) {
                is_found = true;                            
            }
        });

        if (is_found) { return; }
        found.push(row);
        output.push(row);

    });
}
else {

    angular.forEach(collection, function (row) {
        var item = row[keyname];
        if (item === null || item === undefined) return;
        if (keys.indexOf(item) === -1) {
            keys.push(item);
            output.push(row);
        }
    });
}

return output;
};
});

আপনার মার্কআপ আপডেট করুন:

<select ng-model="orderProp" >
   <option ng-repeat="place in places | unique" value="{{place.category}}">{{place.category}}</option>
</select>

0

এটি ওভারকিল হতে পারে তবে এটি আমার পক্ষে কাজ করে।

Array.prototype.contains = function (item, prop) {
var arr = this.valueOf();
if (prop == undefined || prop == null) {
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] == item) {
            return true;
        }
    }
}
else {
    for (var i = 0; i < arr.length; i++) {
        if (arr[i][prop] == item) return true;
    }
}
return false;
}

Array.prototype.distinct = function (prop) {
   var arr = this.valueOf();
   var ret = [];
   for (var i = 0; i < arr.length; i++) {
       if (!ret.contains(arr[i][prop], prop)) {
           ret.push(arr[i]);
       }
   }
   arr = [];
   arr = ret;
   return arr;
}

স্বতন্ত্র ফাংশন উপরে সংজ্ঞায়িত ফাংশনগুলির উপর নির্ভর করে। এটিকে বলা যেতে পারে array.distinct(prop);যেখানে প্রোপ সেই সম্পত্তি যেখানে আপনি স্বতন্ত্র হতে চান।

সুতরাং আপনি শুধু বলতে পারে $scope.places.distinct("category");


0

আপনার নিজের অ্যারে তৈরি করুন।

<select name="cmpPro" ng-model="test3.Product" ng-options="q for q in productArray track by q">
    <option value="" >Plans</option>
</select>

 productArray =[];
angular.forEach($scope.leadDetail, function(value,key){
    var index = $scope.productArray.indexOf(value.Product);
    if(index === -1)
    {
        $scope.productArray.push(value.Product);
    }
});
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.