19

In one component I can filter my array using the following:

// Array of product objects
const result = products.filter(p => p.name.includes('val'));

and value of products remains same as the first value but filtered value stores in result.

But in the following code, filter() filters array of strings itself:

// Array of strings
const result = strs.filter(s => s.includes('val'));

The question is how can I filter strings and return result without modifying the strs itself?

Note: I tried with array.filter(function() { return res; }); but didn't make any change.

2
  • This strs.filter(s => s.includes('val')); does not modify strs. The filter function returns a new array with the items for which the predicate you pass in the filter function is true. Commented Nov 11, 2017 at 8:13
  • your code is fine , there might be some typo Commented Nov 11, 2017 at 8:13

2 Answers 2

21

It returns the filtered ones and don't change the actual array. You are doing something wrong

const strs = ['valval', 'bal', 'gal', 'dalval'];
const result = strs.filter(s => s.includes('val'));

console.log(strs);
console.log(result);

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, you're right, the problem was because of an object containing an array of another object. I changed my mind about the way I filter and it works properly. Thank you
2

First thing we need to know is, if we filter our list we loose our original data

products: any[] = [
 {
  "productId": 1,
  "productName": "foo-bar",
  "price": 32.99
 }
]

and can't get it back without re-getting the data from it's source so we have to make another list to store the filtered list.

 filteredProduce: any[];

Next if you are working to show a list of filtered product on a grid or something like this we need a way to know when the user changes the filter criteria. we could use event binding and watch for key presses or value changes, but an easier way is to change our _listFilter property into a getter and setter, like this

get listFilter: string {
    return this._listFilter;
}
set listFilter(value:string) {
    this._listFilter= value;
}

next we want to set our filteredProducts array to the filtered list of products like this

set listFilter(value:string) {
    this._listFilter= value;
    this.filteredProducts = this._listFilter? this.performFilter(this._listFilter) : this.products;
}

in preceding code we are using js conditional operator to handle the posibility that _listFilterstring is empty, null or undefined. Next we use this.performFilter(this._listFilter) to filter our list.

performFilter(filterBy: string): any[] {
    filterBy = filterBy.toLocaleLowerCase();
    return this.products.filter((product: any) =>
        product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1);
}

Finally we should assign the main list of products to the filteredProducts and _listFilter to what we want.

constructor() {
        this.filteredProducts = this.products;
        this._listFilter= 'foo-bar';
    }

last step is to change our template to bind to our filteredProducts property.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.