如何根據來自另一個對象的匹配值對對象數組進行篩選或自定義篩選

[英]How to filter or custom filter array of objects based on matching values from another object


I implemented an advance search with 15 input fields in AngularJS.

我用AngularJS實現了15個輸入字段的提前搜索。

In the page load itself the result set is return from database in JSON format and i need to do the filter in client side only.

在頁面加載本身中,結果集以JSON格式從數據庫返回,我只需要在客戶端進行篩選。

The input criteria's equivalent column is available in the result set and i need to check in its respective column only.

輸入條件的等效列在結果集中是可用的,我只需要檢查它各自的列。

I am converting each column by JSON.stringify() and check with the search params like the below :

我將JSON.stringify()轉換每一列,並使用如下所示的搜索參數:

$scope.filteredData = $scope.actualData.filter(function(item) {
    return JSON.stringify(item.FirstName).toLowerCase().indexOf(lowerFirstName) != -1 &&
    JSON.stringify(item.LastName).toLowerCase().indexOf(lowerLastName) != -1 &&
    JSON.stringify(item.EmailAddress).toLowerCase().indexOf(lowerEmailAddress) != -1 &&
    JSON.stringify(item.Address1).toLowerCase().indexOf(lowerAddress1) != -1 &&
    JSON.stringify(item.Address2).toLowerCase().indexOf(lowerAddress2) != -1;
    ...... etc // upto 15 fields
});

Since i have the 15 input fields and the actual result set contains a minimum of 50,000 records.

因為我有15個輸入字段,而實際的結果集包含至少50,000條記錄。

So converting each record's each column by JSON.stringify() and check with search params will surely cause the performance issue.

因此,通過JSON.stringify()轉換每個記錄的每一列,並使用搜索參數對其進行檢查,肯定會導致性能問題。

Is there any other way to achieve the filtering in client side with other approach.

是否有其他方法來實現客戶端過濾。

I posted a sample code in Plunker with 5 input fields only : http://plnkr.co/edit/nUWZEbGvz7HG6gb91YZP

我在Plunker中發布了一個只有5個輸入字段的示例代碼:http://plnkr.co/edit/nUWZEbGvz7HG6gb91YZP

2 个解决方案

#1


2  

sylwester's answer is the normal way you'd filter things. Your code looks like you want to filter down to only the object that matches every input field. You code attempts to find an object where every property matches the searchParams object. At that point, I don't see what benefit there is to finding that object, because the user already created the object again! Nonetheless, here's a proper version of your code:

sylwester的答案是你過濾事物的正常方式。您的代碼看起來似乎只希望過濾到與每個輸入字段匹配的對象。編寫代碼試圖找到一個對象,其中每個屬性都與searchParams對象匹配。在這一點上,我看不出找到那個對象有什么好處,因為用戶已經再次創建了對象!盡管如此,這里有一個合適的代碼版本:

Live demo here.

現場演示。

<div ng-repeat="data in actualData | filter:searchData()">
 $scope.searchData = function() {
    return function(item) {
      return Object.keys(item).every(function(key) {
        // skip the $$hashKey property Angular adds to objects
        if (key === '$$hashKey') { return true; }
        var searchKey = key.charAt(0).toLowerCase()+key.slice(1);
        return item[key].toLowerCase() === $scope.searchParams[searchKey].toLowerCase();
      });
    };
  };

You really need to limit the data coming from the server for the browser's sake and for the server's sake. It's easy to implement a LIMIT, OFFSET system. It sounds like, overall, you just need to be able to query the server for a certain record.

為了瀏覽器和服務器,您確實需要限制來自服務器的數據。它很容易實現一個限制,偏移系統。總的來說,您需要能夠查詢服務器上的某條記錄。

From your comments, it seems you definitely want Angular's built in filter filter:searchParams, and just capitalize your searchParams models to match your data. For fun, I'll include more options for finer tuning.

從你的評論來看,似乎你肯定想要角的內置過濾器:searchParams,並只是大寫您的searchParams模型以匹配您的數據。為了好玩,我將提供更多的選項來進行更好的調優。

This one almost mimics filter:searchParams. You can change > 1 to adjust when the partial matching kicks in, or have it return true only when both items are strictly equal === to disable partial matching. The difference here is that all items are hidden until matched, whereas filter:searchParams will show all items and then remove what doesn't match.

這個幾乎是模仿過濾器:searchParams。您可以更改> 1以在部分匹配開始時進行調整,或者僅在兩個項嚴格相等=== ==時返回true以禁用部分匹配。這里的不同之處在於,所有的項都被隱藏直到匹配,而filter:searchParams將顯示所有的項,然后刪除不匹配的項。

Live demo here.

現場演示。

  $scope.searchData = function() {
    return function(item) {
      return Object.keys(item).some(function(key) {
        if (key === '$$hashKey') { return false; }
        var searchKey = key.charAt(0).toLowerCase()+key.slice(1);
        var currentVal = $scope.searchParams[searchKey].toLowerCase();
        var match = item[key].toLowerCase().match(currentVal);
        return currentVal.length > 1 && match;
      });
    };
  };

Lastly, to perfectly mimic filter:searchParams, you'd just put in a check to NOT filter the items until there is user input and the input is long enough to start the partial match.

最后,為了完美地模擬過濾器:searchParams,您只需輸入一個檢查,直到用戶輸入和輸入足夠長,才能開始部分匹配為止。

Live demo here.

現場演示。

  $scope.searchData = function() {
    var partialMatchLength = 2;
    return function(item) {
      var shouldFilter = Object.keys($scope.searchParams).some(function(key) {
        return $scope.searchParams[key] && $scope.searchParams[key].length >= partialMatchLength;
      });
      if (!shouldFilter) { return true; }
      return Object.keys(item).some(function(key) {
        if (key === '$$hashKey') { return false; }
        var searchKey = key.charAt(0).toLowerCase()+key.slice(1);
        var currentVal = $scope.searchParams[searchKey].toLowerCase();
        var match = item[key].toLowerCase().match(currentVal);
        return currentVal.length >= partialMatchLength && match;
      });
    };
  };

#2


1  

First of all you ng-repeter with 50.000 records more likely is going to kill your browser, so you should thing about pagination. Secondly you can easy filter your data using angular filter please see that demo

首先,有50000個記錄的ng-repeter可能會殺死你的瀏覽器,所以你應該考慮分頁。第二,你可以很容易地用角濾波器過濾你的數據,請看演示

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

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

<div ng-controller="ListCtrl">
    <br />
    First Name:
    <input type="text" id="txtFirstname" ng-model="searchParams.FirstName">
    <br/>Last Name:
    <input type="text" id="txtLastname" ng-model="searchParams.LastName">
    <br/>Email Address:
    <input type="text" id="txtEmailAddress" ng-model="searchParams.EmailAddress">
    <br/>Address 1:
    <input type="text" id="txtAddress1" ng-model="searchParams.Address1">
    <br/>Address 2:
    <input type="text" id="txtAddress2" ng-model="searchParams.Address2">
    <br/>
    <button class="btn btn-primary" ng-click="searchData()">Search</button>
    <br />
    <hr />
    <b>Filtered Data(s):</b>
    <div ng-repeat="data in actualData | filter:searchParams ">
      <span ng-bind="data.FirstName"></span>
      <span ng-bind="data.LastName"></span> |
      Address : {{data.Address1}}
    </div>
    <hr />

  </div>

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2015/03/11/abfdb11d502aaa371851c7791e2444df.html



 
粤ICP备14056181号  © 2014-2021 ITdaan.com