Собственный тип данных для этого результата JSON: List<Dictionary<string, string[]>>
.Вы можете проанализировать его напрямую с помощью:
var cars = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Dictionary<string, string[]>>>(json);
И затем вы можете создать некоторые функции для поиска по этим данным:
private int HouseholdWith(List<Dictionary<string, string[]>> cars, string car1)
{
return cars.Count(household => household["car"].Any(c => c == car1));
}
private int HouseholdWith(List<Dictionary<string, string[]>> cars, string car1, string car2)
{
return cars.Count(household => household["car"].Any(c => c == car1) && household["car"].Any(c => c == car2));
}
private int HouseholdWithOnly(List<Dictionary<string, string[]>> cars, string car)
{
return cars.Count(household => household["car"].All(c => c == car));
}
Если вы хотите реорганизовать данные из JSON в домохозяйства, вы можете сделать что-то вроде этого:
class Household
{
public List<string> Cars { get; set; }
}
var cars = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Dictionary<string, string[]>>>(json);
List<Household> households = (
from h in cars
select new Household()
{
Cars = h["car"].ToList()
}
).ToList();
С измененными функциями поиска:
private int HouseholdsWith(List<Household> households, string car1)
{
return households.Count(h => h.Cars.Any(c => c == car1));
}
private int HouseholdsWith(List<Household> households, string car1, string car2)
{
return households.Count(h => h.Cars.Any(c => c == car1) && h.Cars.Any(c => c == car2));
}
private int HouseholdsWithOnly(List<Household> households, string car)
{
return households.Count(h => h.Cars.All(c => c == car));
}
И для проверки:
Console.WriteLine("Households who have only BMW 760 are {0}", HouseholdsWithOnly(households, "BMW 760"));
//Households who have only BMW 760 are 2
Console.WriteLine("Households who have BMW 760 are {0}", HouseholdsWith(households, "BMW 760"));
//Households who have BMW 760 are 3
Console.WriteLine("Households with Civic and Camry are {0}", HouseholdsWith(households, "Honda Civic", "Toyota Camry"));
//Households with Civic and Camry are 2
Console.WriteLine("Households with only Civic is {0}", HouseholdsWithOnly(households, "Honda Civic"));
//Households with only Civic is 1
ИМХО, ваши классы десериализациидля Newtonsoft должно быть максимально просто.Newtonsoft является мощным средством, и вы можете многое сделать в процессе десериализации, но чем проще, тем легче будет вносить изменения, если в будущем необходимо изменить структуру данных.Ваша функция отображения после десериализации - это то, где вы превращаете данные во что-то полезное для вашего приложения.Я думаю, что это хороший принцип SoC.
Бонус-раунд
private void CreateReport(List<Household> households)
{
//get all unique cars
List<string> cars = households.SelectMany(h => h.Cars).Distinct().OrderBy(c => c).ToList();
foreach(string c in cars)
{
Console.WriteLine("Households with {0}: {1}", c, HouseholdsWith(households, c));
Console.WriteLine("Households with only {0}: {1}", c, HouseholdsWithOnly(households, c));
}
//Get each unique pair
var pairs = households.Where(h => h.Cars.Count > 1).SelectMany(h =>
{
List<Tuple<string, string>> innerpairs = new List<Tuple<string, string>>();
for (int i = 0; i < h.Cars.Count - 1; i++)
{
for (int j = i + 1; j < h.Cars.Count; j++)
{
if (string.Compare(h.Cars[i], h.Cars[j]) < 0)
{
innerpairs.Add(new Tuple<string, string>(h.Cars[i], h.Cars[j]));
}
else
{
innerpairs.Add(new Tuple<string, string>(h.Cars[j], h.Cars[i]));
}
}
}
return innerpairs;
}).Distinct().ToList();
foreach (var p in pairs)
{
Console.WriteLine("Households with {0} and {1}: {2}", p.Item1, p.Item2, HouseholdsWith(households, p.Item1, p.Item2));
}
}
Создает вывод вроде:
Households with BMW 760: 3
Households with only BMW 760: 2
Households with Honda Civic: 3
Households with only Honda Civic: 1
Households with Honda Odyssey: 2
Households with only Honda Odyssey: 0
Households with Mercedes S: 1
Households with only Mercedes S: 0
Households with Smart Car: 1
Households with only Smart Car: 0
Households with Tesla X: 2
Households with only Tesla X: 0
Households with Toyota Camry: 2
Households with only Toyota Camry: 0
Households with Honda Civic and Toyota Camry: 2
Households with BMW 760 and Mercedes S: 1
Households with BMW 760 and Smart Car: 1
Households with Mercedes S and Smart Car: 1
Households with Honda Odyssey and Tesla X: 2