На основе 2 классов
public class Res{
public string Key;
public int Val;
}
public class Reduced
{
public string Key;
public IEnumerable<Res>[] invalid;
}
Вы можете использовать этот код для агрегирования результатов.
var loc =
locationOutputDistinct
.Select(x => x.Trim().Split(' ').ToArray()
.Select(
y => {
var kv = y.Split(':');
return new Res()
{
Key = kv[0],
Val = int.Parse
(kv[1])
};
}).ToArray()).ToArray()
.GroupBy(x =>
String.Join(",",
x.Select(y => y.Key))
);
Тогда вы должны применить правило сокращения
var reduced =
loc.Select(x => new Reduced() {
Key = x.Key,
invalid =
x.Where(y => loc.Any(ext => ext.Any(xsup =>
y.All(z => xsup.Any(xsupcell => xsupcell.Key == z.Key)) &&
y.All(z =>
z.Val <= xsup
.Where(xsupcell =>
xsupcell.Key == z.Key)
.First().Val) &&
((xsup.Length > y.Length) ||
y.Any(z =>
z.Val < xsup
.Where(xsupcell =>
xsupcell.Key == z.Key)
.First().Val))
))).ToArray()
});
var remain = loc.Select(x => x.Where(y =>
!reduced.Where(r => r.Key == x.Key).SelectMany(r2 => r2.invalid).Any(r3 => r3.All(r4 =>
y.Any(y2 => y2.Key == r4.Key && y2.Val == r4.Val)))));
Из вашего последнего примера я вижу, что вы хотите уменьшить также менее расширенные комбинации y
с более расширенными (xsup.Length > y.Length
), поэтому я включил эту последнюю функцию в приведенный выше код.
На этом этапе вам нужно развернуть и распечатать результаты.
foreach (var x in remain)
Console.WriteLine
(//x.Key+": " +
String.Join("\n",
x.Select(y =>
String.Join(" ",
y.Select(z => z.Key + ":" + z.Val)
))));
Из оригинальной последовательности в вашем вопросе вы получите
PERSON:6
PERSON:3 SCOOTER:1
PERSON:4 BIKE:1
PERSON:1 BIKE:1 SCOOTER:1
и от
"AM:4 SC:1 ",
"AM:4 WC:1 ",
"AM:4 WC:1 SC:1 ",
"AM:4 WC:2 ",
"AM:4 WC:2 SC:1 ",
"AM:5 ",
"AM:5 WC:1 ",
"AM:6 ",
"AM:6 WC:1 ",
"AM:7 ",
"AM:8 "
вы получите
AM:6 WC:1
AM:4 WC:2 SC:1
AM:8
Скрипка здесь .