skip to Main Content

I have an array of objects, shown here in a somewhat reduced form.
I want to be able to search for different search terms. On the one hand, I would like to get all objects that contain all search terms, and on the other hand, all objects that contain any search term. The number of search terms is dynamic.

e.g. for (x1 and x2) , (x1 or x2)

Of course I can do this with a loop, but is there also a way to solve the problem with filter … include …

[
    {
      "produkt": "Produkt 1",
      "description": "x1, x2, x3, x4"
    },
    {
      "produkt": "Produkt 1",
      "description": "x2, x3"
    },
    {
      "produkt": "Produkt 1",
      "description": "x1, x4"
    }
]

2

Answers


  1. This might be a little convoluted, but if you want a reusable function you can call with your products and search terms this is an efficient way to get both the products with all search terms and those with any of them. It will also only iterate through your product list once, though it will iterate through search terms multiple times.

    Using Typescript:

    const produkts = [
            {
                "produkt": "1",
                "description": "x1, x2, x3, x4"
            },
            {
                "produkt": "2",
                "description": "x3"
            }
        ]
    
        const findProdukts = (produkts, searchTerms: string[]) => {
            let results = {
                matchesAll: [],
                matchesSome: []
            }
    
            return produkts.reduce((acc: {matchesAll: [any], matchesSome: [any]}, val: {produkt: string, description: string}) => {
                return {
                    matchesAll: searchTerms.every(search => val.description.includes(search)) ? [...acc.matchesAll, val] : [...acc.matchesAll],
                    matchesSome: searchTerms.some(search => val.description.includes(search)) ? [...acc.matchesSome, val] : [...acc.matchesSome]
                }
            }, results)
        }
    
        console.log(findProdukts(produkts, ["x2", "x3"]))
    

    Using Javascript:

    const produkts = [
        {
            "produkt": "1",
            "description": "x1, x2, x3, x4"
        },
        {
            "produkt": "2",
            "description": "x3"
        }
    ]
    
    const findProdukts = (produkts, searchTerms) => {
        let results = {
            matchesAll: [],
            matchesSome: []
        }
    
        return produkts.reduce((acc, val) => {
            return {
                matchesAll: searchTerms.every(search => val.description.includes(search)) ? [...acc.matchesAll, val] : [...acc.matchesAll],
                matchesSome: searchTerms.some(search => val.description.includes(search)) ? [...acc.matchesSome, val] : [...acc.matchesSome]
            }
        }, results)
    }
    
    console.log(findProdukts(produkts, ["x2", "x3"]))
    Login or Signup to reply.
  2. If you are looking for a performance, this solution should work very well:

    const produkts = [
      {
        produkt: 'Produkt 1',
        description: 'x1, x2, x3, x4',
      },
      {
        produkt: 'Produkt 1',
        description: 'x2, x3',
      },
      {
        produkt: 'Produkt 1',
        description: 'x1, x4',
      },
    ];
    
    const filterItems = (produkts = [], searchTerms = []) => {
      const regexps = searchTerms.map((searchTerm) => new RegExp(searchTerm, 'i'));
      const results = { containAll: [], containAny: [] };
    
      produkts.forEach((produkt) => {
        const matches = regexps.map((regexp) => regexp.test(produkt.description)).filter((isMatch) => isMatch).length;
    
        if (matches) {
          results.containAny.push(produkt);
          if (matches === regexps.length) {
            results.containAll.push(produkt);
          }
        }
      });
    
      return results;
    };
    
    console.log(filterItems(produkts, ['x1', 'x2']));
    

    The function is optimized by using regular expressions for flexible and efficient matching, counting matches for each product to avoid unnecessary operations, and directly accumulating results without creating new arrays, reducing memory overhead.
    Filters a list of products based on a list of search terms. It creates regular expressions for each search term and checks if the product descriptions match. It categorizes products into two groups: containAll (products that match all search terms) and containAny (products that match at least one search term). The function returns an object containing these two categories.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search