开发者

How to sort linq result by most similarity/equality

开发者 https://www.devze.com 2022-12-27 05:58 出处:网络
I want to do a search for Music instruments which has its informations Name, Category and Origin as I asked in my post.

I want to do a search for Music instruments which has its informations Name, Category and Origin as I asked in my post.

But now I want to sort/group the result by similarity/equality to the keyword such as. If I have the list

{ Drum, Grand Piano, Guitar, Guitarrón, Harp, Piano} << sorted by name

and if I queried "p" the result should be { Piano, Grand Piano, Harp }

but it shows Harp first because of the source list's sequence

and if I add {Grand Piano} to the list and query "piano"

the result shoud be like { Piano, Grand Piano }

or query "guitar" it s开发者_Python百科hould be { Guitar, Guitarrón }

here's my code

static IEnumerable<MInstrument> InstrumentsSearch(IEnumerable<MInstrument> InstrumentsList, string query, MInstrument.Category[] SelectedCategories, MInstrument.Origin[] SelectedOrigins)
{
    var result = InstrumentsList
        .Where(item => SelectedCategories.Contains(item.category))
        .Where(item => SelectedOrigins.Contains(item.origin))
        .Where(item =>
            {
                if (
                        (" " + item.Name.ToLower()).Contains(" " + query.ToLower())
                        || item.Name.IndexOf(query) != -1
                    )
                {
                    return true;
                }
                return false;
            }
        )
        .Take(30);

    return result.ToList<MInstrument>();
}

Or the result may be like my old self-invented algorithm that I called "by order of occurence",

that is just OK to me.

And the further things to do is I need to search the Name, Category or Origin such as.

If i type "Italy" it should found Piano or something from Italy.

Or if I type "string" it should found Guitar.

Is there any way to do those things, please tell me.

Thanks in advance.


You want OrderBy / OrderByDescending --

result = InstrumentsList.
     .Where(...)
     .OrderByDescending(instrument => 
         StringSimilarityScore(instrument.Name, searchString))
     .Take(30);

As to the definition of StringSimilarityScore -- a full-on fuzzy match would be best, but you could start by quantifying the match based on the proportion of the name matched by the search string:

double StringSimilarityScore(string name, string searchString)
{
    if (name.Contains(searchString))
    {
        return (double)searchString.Length / (double)name.Length;
    }

    return 0;
}

You might then want to consider the position of the search string within the name (earlier is better), for the cases where a single letter is specified -- but I'll leave that up to you. :-)

0

精彩评论

暂无评论...
验证码 换一张
取 消