我有一个字符串列表,我想选择包含最小数量~
或>
或|
我提出的所有解决方案都给出了最小计数,而不是具有最小计数的字符串。
有什么想法吗?
到目前为止我所拥有的:
private string FilterShortestPath(List<string> paths)
{
return paths.Min(x => x.Count(c => c == '~' || c == '>' || c == '|'));
}
答案 0 :(得分:2)
如果要查找具有最小计数的所有字符串,可以使用Where
:
private IEnumerable<string> FilterShortestPath(IEnumerable<string> paths, params char[] chars)
{
if(paths == null || !paths.Any())
return Enumerable.Empty<string>();
int minCount = paths.Min(str => (str ?? "").Count(chars.Contains));
return paths.Where(str => (str ?? "").Count(chars.Contains) == minCount);
}
用法:
var minCountStrings = FilterShortestPath(list, '~', '>' , '|');
请注意,如果由于延迟执行而只需要此方法,也可以使用此方法。然后你只需要使用FilterShortestPath(list, '~', '>' , '|').First()
。
答案 1 :(得分:1)
如果我的任务正确:
var strings = new []{"~~~~", "wwqewqe>", "||"};
var chars = new[] {'~', '|', '>'};
var result = strings.OrderBy(s => s.Count(c => chars.Contains(c))).First();
答案 2 :(得分:0)
您可以使用带有谓词的IEnumerable<T>.Count
方法执行此操作,并且该谓词检查char是否存储在可接受字符的集合中。
String[] strings = new String[] {"<todo|>","~foo"};
HashSet<char> accept = new HashSet<char>(new char[] {'~','>','|'});
strings.ArgMin(x => x.Count(accept.Contains));
使用:
public static TS ArgMin<TS,TF> (this IEnumerable<TS> source, Func<TS,TF> f) where TF : IComparable<TF> {
if(source == null) {
throw new ArgumentException("Source must be effective.");
}
IEnumerator<TS> en = source.GetEnumerator();
if(!en.MoveNext()) {
throw new ArgumentException("You need to provide at least one argument.");
}
TS x0 = en.Current, xi;
TF f0 = f(x0), fi;
while(en.MoveNext()) {
xi = en.Current;
fi = f(xi);
if(f0.CompareTo(fi) > 0) {
f0 = fi;
x0 = xi;
}
}
return x0;
}
ArgMin
会返回IEnumerable<T>
中以最小值应用f
后产生的项目。如果多个值导致相同的值,则选择第一个值。如果未提供任何项目,或者列表无效,则会引发异常。
答案 3 :(得分:0)
以下代码
var badChars = new[] { '~', '>', '|' };
var strings = new[]
{
"I ~ love >> cookies |||",
"I >>>> love pizza ~",
"I hate tildas~~"
};
var grouped = from str in strings
let count = str.Count(c => badChars.Contains(c))
orderby count ascending
select new { Text = str, Count = count };
var tuple = grouped.First();
Console.WriteLine("Text is '{0}' with {1} occurences", tuple.Text, tuple.Count);
应该为做一件事。但是,由于您可能需要多个最小值,因此以下一个应该有所帮助:
var badChars = new[] { '~', '>', '|' };
var strings = new[]
{
"I ~ love >> cookies |||",
"I >>>> love pizza ~",
"I hate tildas~~",
"Bars are also | | bad"
};
var grouped = (from str in strings
let count = str.Count(c => badChars.Contains(c))
orderby count ascending
select new { Text = str, Count = count }).ToList();
int min = grouped[0].Count;
var minimums = grouped.TakeWhile(g => g.Count == min);
foreach(var g in minimums)
Console.WriteLine("Text is '{0}' with {1} occurences", g.Text, g.Count);