How to filter items that do not contain a word in a list?

Asked

Viewed 897 times

6

I have a: List<Grupos> lista = new List<Grupos>();

And I have this code

var txtFiltro = "noivas,unhas";
var palavrasFiltro = txtFiltro.ToLower().Split(',');
matches = lista.Where(x => !palavrasFiltro.Contains(x.Nome_Grupo.ToLower().ToString())).ToList();

This code filters everything that is different from the text I am informing, but only works if you have one word, if you have phrases does not work, as could do the implementation of this filter?

Here is a code that the user @jbueno helped me.

  • What is a phrase for you? It is to work with sentences yes, the search for text does not stop in white spaces.

  • You want to know if a larger string nay contains the words listed in wordFilter?

  • Let’s say that in my List I have 10 records within these 10 records I have phrases ex: "I like potato", "I like strawberry", "I like orange". In my filter I want my List to display everything that does not contain the word "orange". That way my list would only have the records "I like potato", "I like strawberry".

  • But this is already doing.

  • It’s not! It doesn’t work with sentences if it was just inside the list the word "orange" would work.

  • But you just spoke in the example of the comment that is what you want. I will repeat what I asked: define for you what is a phrase.

  • Guys, I’ll try to explain again. I have a list. var list = new[] { new{Name_group = "On-call Bride"}, new{Name_group = "Brides 2016/ 2017 - RJ"}, new{Name_group = "Brides Goianas"}, new{Name_group = "GOD ABOVE EVERYTHING"}, new{Group name = "In the Lap of Our Lady"}, }; Now I need that when I type a word ex: "God" the List returns to me all items that DO NOT contain the word "God". In this case Above would return me items 1,2,3 and 5. Item 4 would be the item that my filter has.

Show 2 more comments

2 answers

6


The algorithm presented in link is wrong. You’re looking for the phrase within words, it’s not going to work at all. You can’t look for a larger text inside a smaller one, the larger one will never be inside the smaller one. If this is what you wanted, it’s mathematically impossible and it doesn’t make any sense.

If you are looking for sentences, just use the phrase. The space between words will not disturb anything.

If you want to use a few loose words as a filter, you need to create a more complex filter mechanism. Although you can do 100% on LINQ I find it interesting to create an extension method that solves this (you can even use LINQ on it, if you like). It doesn’t even need to be an extension method, but it is more convenient to use it.

This method has to verify that each of the strings used in the filter is contained within each sentence.

It has more performative ways of doing this, but it’s more complex, I don’t know if it pays.

public static bool ContainsAny(this string haystack, params string[] needles) {
    foreach (var needle in needles) {
        if (haystack.Contains(needle)) return true;
    }
    return false;
}

Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.

Form with LINQ:

public static bool ContainsAny(this string haystack, params string[] needles) => needles.Any(x => haystack.Contains(x));

In fact, if you want to make sure it’s just exact words, it complicates things. This example (based on the previous one applied, so if it does not do what it wants, the other will not do it either) if you look for "bride", you will find "betrothal", even if you do not want this. This search is not for words, it is for text snippets, it does not observe the syntax of the text.

If I wanted to solve this naively I would have to separate the phrase into words and verify the equality of each one.

Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.

This does not solve all cases. A Parsing more complete is necessary to meet all cases, then becomes complicated.

Then you must think: if I want "bride" and "bride"? You have to treat it as if it were two words. The same goes for verb conjugation, gender change, etc.

  • Perfect! Thank you bigown!!!

  • Would it be too complicated to search for exact word? I ended up falling in this case that you told me about the "bride", will find "betrothal",

  • Doing right is a little complicated, doing more or less is easy. I’ll try for an example.

  • Beauty I’ll be waiting, thank you!

  • 1

    Just to explain: The link algorithm is only wrong because it comes from an unclear question. I say here in this comment

3

I think the problem is that you are looking for the larger string inside the smaller one, i.e.: you are seeing if the filter contains the phrase and not the other way around.

I suggest:

string[] palavrasFiltro; // mantive array porque é o que você usa...
List<string> lista; // ... mas eu prefiro trabalhar com listas. Suas frases ficam aqui.
List<string> remocao = new List<string>();

foreach (string elemento in lista)
{
    foreach (string filtro in palavrasFiltro)
    {
        if (elemento.Contains(filtro))
        {
            remocao.Add(elemento);
            break;
        }
    }
}

foreach (string s in remocao)
{
    lista.Remove(s);
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.