Question:
I have a string
list:
AAA
BBB
CCC
ABB
ABC
ACC
ACD
The user will type what he is looking for, he would like to take it to the first positions, the most similar ones. Example:
String: A
Result:
AAA
ABB
ABC
ACC
ACD
BBB
CCC
String: AB
Result:
ABB
ABC
AAA
ACC
ACD
BBB
CCC
String: C
Result:
CCC
AAA
ABB
ABC
ACC
ACD
BBB
String: AC
Result:
ACC
ACD
AAA
ABB
ABC
CCC
BBB
String: B
Result:
BBB
AAA
ABB
ABC
ACC
ACD
CCC
Edit:
Just incrementing @maniero's solution that worked perfectly:
lista.OrderByDescending(x => (x.StartsWith(padrao))).ThenByDescending(x => (x.Contains(padrao)));
And that way I got an even better result than expected.
Answer:
What appears to have been defined as similar is whether the substring exists in the string of each element in the list. So just order the ones you have first, so the OrderByDecending()
applied to Contains()
. It will group everything that contains and then what does not contain the text pattern.
using System;
using System.Collections.Generic;
using System.Linq;
public class Program {
public static void Main() {
var lista = new List<string> { "AAA", "BBB", "CCC", "ABB", "ABC", "ACC", "ACD" };
Semelhante(lista, "A");
Semelhante(lista, "B");
Semelhante(lista, "C");
Semelhante(lista, "AB");
Semelhante(lista, "AC");
}
public static void Semelhante(List<string> lista, string padrao) {
foreach (var item in lista.OrderByDescending(x => (x.Contains(padrao)))) {
Console.WriteLine(item);
}
Console.WriteLine();
}
}
See it working on ideone . And in .NET Fiddle . I also put it on GitHub for future reference .
In a new edition of the question there is an even better option, but only the AP knew that was what it needed.
Previously I interpreted what resemblance was differently. It's just to try to help someone else.
I think it can be improved and I haven't fully tested it. gambi alert to use only LINQ 😛
OrderBy()
waits for the element that should be used for it to sort, that is, what the key should be. So I'm sending him the number of occurrences of the substring that he found as a key, after all, the more occurrences, the closer it is. I used Count()
on the string to find the number of occurrences.
It may be that the "similar" requirement was not quite that one, but the question doesn't make it so clear. The result is as expected.
I don't know if AAB is better than ABC because it has 2 Bs or if B comes before C (mine got it like that).
using System;
using System.Collections.Generic;
using System.Linq;
public class Program {
public static void Main() {
var lista = new List<string> { "AAA", "BBB", "CCC", "ABB", "ABC", "ACC", "ACD" };
var padrao = "A";
foreach (var item in lista.OrderByDescending(x => x.Select((c, i) => x.Substring(i)).Count(sub => sub.StartsWith(padrao)))) {
Console.WriteLine(item);
}
Console.WriteLine();
padrao = "AB";
foreach (var item in lista.OrderByDescending(x => x.Select((c, i) => x.Substring(i)).Count(sub => sub.StartsWith(padrao)))) {
Console.WriteLine(item);
}
}
}
See it working on ideone . And in .NET Fiddle . I also put it on GitHub for future reference .