web-dev-qa-db-ja.com

1つのパイプを使用して複数の列をフィルターangular 2

1つのArrayのみを使用して、複数の列に基づいてPipeデータをフィルタリングしようとしています。現在、最初の列の値をフィルタリングします。以下のコードを確認して、これを整理してください。

マイコード:

@Pipe({ name: "dataFilter", pure: false })
export class DataFilterPipe implements PipeTransform {
    transform(value: Array<any>, filter: any[]) {
        if (!filter) {
            return value;
        } else if (value) {
            return value.filter(item => {
                for (var i = 0; i < filter.length; i++) {
                    if (filter[i][1] == undefined) {
                        return true;
                    } else if ((typeof item[filter[i][0]] === 'string' || item[filter[i][0]] instanceof String) &&
                        (item[filter[i][0]].toLowerCase().indexOf(filter[i][1]) !== -1)) {
                        return true;
                    }
                    return false;
                }
            });
        }
    }
}

dataFilter : [['column1',value1],['column2',value2],['column3',value3]]のようなデータを渡します。

15
Jeeten Parmar

以下は、複数列フィルターとして渡されたオブジェクトを使用したソリューションです。 2D配列を渡すよりも便利だと思いました。

    @Pipe({
        name: 'filter'
    })
    export class FilterPipe implements PipeTransform {
        transform(items: Array<any>, filter: {[key: string]: any }): Array<any> {
            return items.filter(item => {
                let notMatchingField = Object.keys(filter)
                                             .find(key => item[key] !== filter[key]);

                return !notMatchingField; // true if matches all fields
            });
        }
    }

複数の列を持つオブジェクトの配列を持つ:

this.people = [
  {name: 'John', age: 27, sex: 'male'},
  {name: 'Lara', age: 21, sex: 'female'},
  {name: 'Rick', age: 29, sex: 'male'},
  {name: 'Eva',  age: 27, sex: 'female'},
  {name: 'Mike', age: 27, sex: 'male'}
];

そしてフィルター:

this.peopleFilter = {age: 27, sex: 'male'};

次のように使用します。

 <div *ngFor="let person of people | filter: peopleFilter;"></div>

その結果、2人が基準に一致しています:JohnおよびMike

動作するプランカーは次のとおりです。 複数列フィルターパイプデモ

25
Seid Mehmedovic

私はあなたがこのような列を持つ配列を持っていると仮定しています:

_[{col1:"col1",col2:"col2",col3:"col3"}]_

また、すべてのタイプチェックイン、ヌルポインター、エラー処理も省略しました。現在の解決策は、配列で試した例です:

_myData:Array<any> = [{col1:"a",col2:"b",col3:"cadd"},
    {col1:"abba",col2:"bobba",col3:"cadd"},
    {col1:"abba",col2:"bobba",col3:"cool"},
    {col1:"a",col2:"bobba",col3:"cool"}];
_

そしてパイプ:

_@Pipe({
  name: 'dataFilter'
})
export class DataFilterPipe implements PipeTransform {

  transform(value: any, args?: any): any {
    return value.filter(item =>{
      var matchesAll = true;
      for(var i = 0; i<args.length; i++){
        // check if your data contains the column and the value defined in args.
        if(item.hasOwnProperty(args[i][0]) && item[args[i][0]]==args[i][1]){
          continue;
        }else{ // at least one column did not match,
          matchesAll = false;
        }
      }
      return matchesAll;
    });
  }

}
_

その後、呼び出すことができます

dataFilter.transform(myData,[["col1","abba"],["col2","bobba"],["col3","cool"]]);

変換後の行番号3である1つの結果を取得するために:_[{col1:"abba",col2:"bobba",col3:"cool"}]_。

注:コードで機能するように、この例の列の名前を調整する必要がある場合があります。

EDIT:このソリューションでは、任意の数の列を渡すこともできます。

例:dataFilter.transform(myData,[["col3","cool"]]);

これは、変換後の最後の2行(私の例から)になります。

_[{col1:"abba",col2:"bobba",col3:"cool"},{col1:"a",col2:"bobba",col3:"cool"}]_

EDIT:コードが機能していないとコメントした後、上記の例のプランカーを提供しました: https://plnkr.co/edit/VdpGJWyzWUVFzYNDSz1g

1
John

以下のようにコードを置き換え、

 export class DataFilterPipe implements PipeTransform {
   transform(value: Item[], field: string, args: string): Item[]{
      let filter: string = args ? args.toLocaleLowerCase() : null;
      return filter ? value.filter((item : Item) =>
          Item[field].toLocaleLowerCase().indexOf(filter) != -1) : value;
   }
}

HTMLページで、

 <tbody *ngFor="let item of items | dataFilter : columnName : value ">
1
Trusha

HTMLマークアップ:

*ngFor="let item of _items | filtername:{ parametername: searchtext, parametername: searchtext } : false"

変換機能:

transform(items: any, filter: any, isAnd: bool): any {
  if (filter && Array.isArray(items)) {
   let filterKeys = Object.keys(filter);
    if (isAnd) {
     return items.filter(item =>
        filterKeys.reduce((memo, keyName) =>
            (memo && new RegExp(filter[keyName], 'gi').test(item[keyName])) || filter[keyName] === "", true));
    } else {
     return items.filter(item => {
      return filterKeys.some((keyName) => {
        console.log(keyName);
        return new RegExp(filter[keyName], 'gi').test(item[keyName]) || filter[keyName] === "";
      });
    });
   }
  } else {
   return items;
  }
}

参照: https://long2know.com/2017/04/angular-pipes-filtering-on-multiple-keys/

0
ANIL PATEL

作業全体ArrayFilterPipe.ts@ http://TypeScript.io/uN29xRdF1Ag または typescriptlang.org
また、希望する出力を見やすくするために、TypeScriptのコンパイルJSを添付しました。コードにコメントが必要かどうかを教えてください...

FYIオプション配列は、フィルターを実行する前にオブジェクトに変換されます。これは、配列が非常に快適だと感じるためです。

/* yours */
var option = [['column1',value1],['column2',value2],['column3',value3]];
/* mine */
var option = { column1: 'value1', column2: 'value2', column3: 'value3' };

static _arrayToObject(value: Array<Array<any>>): any {
    return (ArrayFilterPipe._isUndefined(value) || value == null) 
    ? value 
    : value.reduce((result, current) => {   
                    result[current[0]] = current[1]; 
                    return result; 
                } , {});
}

https://github.com/angular/angular.js/からインスピレーションを得ることで、angular 1.xのような配列/オブジェクトフィルターを構築することもできます。 blob/master/src/ng/filter/filter.js

var ArrayFilterPipe = (function () {
    function ArrayFilterPipe() {
    }
    ArrayFilterPipe._isOfType = function (value, type) {
        return typeof (value) === type;
    };
    ArrayFilterPipe._isUndefined = function (value) {
        return ArrayFilterPipe._isOfType(value, ArrayFilterPipe.TYPES.UNDEFINED);
    };
    ArrayFilterPipe._isObject = function (value) {
        return ArrayFilterPipe._isOfType(value, ArrayFilterPipe.TYPES.OBJECT);
    };
    ArrayFilterPipe._isOrHasMatch = function (value, target) {
        return ArrayFilterPipe._isOfType(value, ArrayFilterPipe.TYPES.STRING) || ArrayFilterPipe._isOfType(target, ArrayFilterPipe.TYPES.STRING)
            ? value.toString().toLowerCase().indexOf(target.toString().toLowerCase()) >= 0
            : value == target;
    };
    ArrayFilterPipe._hasOptions = function (value, options) {
        return (ArrayFilterPipe._isUndefined(value) || ArrayFilterPipe._isUndefined(options) ? (ArrayFilterPipe._isUndefined(value) && ArrayFilterPipe._isUndefined(options))
            : (value === null || options == null) ? (value === null && options == null)
                : (Array.isArray(value) || Array.isArray(options)) ? false
                    : ArrayFilterPipe._isObject(value) ?
                        (ArrayFilterPipe._isObject(options)
                            ? Object.keys(options).every(function (key) { return value.hasOwnProperty(key) && ArrayFilterPipe._isOrHasMatch(value[key], options[key]); })
                            : Object.values(value).some(function (val) { return ArrayFilterPipe._isOrHasMatch(val, options); }))
                        : !ArrayFilterPipe._isObject(value) ?
                            (!ArrayFilterPipe._isObject(options)
                                ? ArrayFilterPipe._isOrHasMatch(value, options)
                                : false)
                            : false);
    };
    ArrayFilterPipe._arrayToObject = function (value) {
        return (ArrayFilterPipe._isUndefined(value) || value == null) ? value : value.reduce(function (result, current) {
            result[current[0]] = current[1];
            return result;
        }, {});
    };
    ArrayFilterPipe.prototype.transform = function (value, options) {
        if (!value || !Array.isArray(value) || ArrayFilterPipe._isUndefined(options) || options === null) {
            return value;
        }
        options = Array.isArray(options) ? ArrayFilterPipe._arrayToObject(options) : options;
        return value.filter(function (item) { return ArrayFilterPipe._hasOptions(item, options); });
    };
    return ArrayFilterPipe;
}());
ArrayFilterPipe.TYPES = {
    OBJECT: 'object',
    STRING: 'string',
    UNDEFINED: 'undefined'
};
/*
    TESTING
    --------------------------------------------------
*/
var pipe = new ArrayFilterPipe();
var array = [null, undefined, , true, 123123, 'Jeke HeNry', 'joe', 'joe hen', {}, [], { fake: 'hen' }, { name: 'hen' }, { name: 'johenrik', country: 'hen' }, { name: 'joe dick', city: 'hen' }, { name: 'Jeke HeNry', country: 'zxy' }];
var options = null;
/* REF:  http://stackoverflow.com/questions/11403107/capturing-javascript-console-log */
var oldLog = console.log;
console.log = function (message) {
    var _arguments = arguments;
    var div = Object.keys(arguments).map(function (key) { return Number(key); }).reduce(function (result, key) {
        result = result || document.createElement('div');
        var isJSON = (_arguments[key] != null && (typeof (_arguments[key]) === 'object' || Array.isArray(_arguments[key])));
        var span = document.createElement(isJSON ? 'pre' : 'span');
        span.innerHTML = isJSON ? JSON.stringify(_arguments[key], undefined) : _arguments[key].replace('\n', '</br></br>');
        result.appendChild(span);
        return result;
    }, null);
    document.body.appendChild(div);
    oldLog.apply(console, arguments);
};
function test() {
    console.log('options', options);
    console.log('result', pipe.transform(array, options));
}
console.log('case : 01');
console.log('---------------------------------------------------');
options = 'hen';
test();
console.log('\ncase : 02');
console.log('---------------------------------------------------');
options = { name: 'hen' };
test();
options = [['name', 'hen']];
test();
console.log('\ncase : 03');
console.log('---------------------------------------------------');
options = { name: 'hen', country: 'hen' };
test();
options = [['name', 'hen'], ['country', 'hen']];
test();
console.log('\ncase : 04');
console.log('---------------------------------------------------');
options = { name: 'hen', city: 'hen', fake: true };
test();
options = [['name', 'hen'], ['country', 'hen'], ['fake', true]];
test();