我有要读取JSON数据的JSON数据(有汽车的家庭)。一个子集如下所示:
[
{
"car":[
"Honda Civic",
"Toyota Camry"
]
},
{
"car":[
"Honda Civic"
]
},
{
"car":[
"BMW 760",
"Mercedes S",
"Smart Car"
]
},
{
"car":[
"Honda Odyssey",
"Tesla X"
]
},
{
"car":[
"BMW 760"
]
},
{
"car":[
"Honda Odyssey",
"Tesla X"
]
},
{
"car":[
"BMW 760"
]
},
{
"car":[
"Toyota Camry",
"Honda Civic"
]
}
]
当我使用以下逻辑读取文件时,文件读取成功。 (我正在使用Newtonsoft.Json
。)
string sJSON = File.ReadAllText(@"D:\MyFolder\cars.json");
List<Car> allCars = JsonConvert.DeserializeObject<List<Car>>(sJSON);
Cars
类是这样:
public class Car
{
private ArrayList carNames = new ArrayList();
public void AddCar(string carName)
{
carNames.Add(carName);
}
}
我面临两个问题:
allCars
。我该如何计算汽车数量?例如:
我试图做this question上提到的操作,但这没用。
答案 0 :(得分:0)
首先必须拼合嵌套的汽车名称列表,然后将它们分组以获得所需的输出。
class Program
{
static void Main(string[] args)
{
string carsData = @"
[
{
'car':[
'Honda Civic',
'Toyota Camry'
]
},
{
'car':[
'Honda Civic'
]
},
{
'car':[
'BMW 760',
'Mercedes S',
'Smart Car'
]
},
{
'car':[
'Honda Odyssey',
'Tesla X'
]
},
{
'car':[
'BMW 760'
]
},
{
'car':[
'Honda Odyssey',
'Tesla X'
]
},
{
'car':[
'BMW 760'
]
},
{
'car':[
'Toyota Camry',
'Honda Civic'
]
}
]
";
List<Car> allCars = JsonConvert.DeserializeObject<List<Car>>(carsData);
// Flatten all the car names first then group them
var carDistributions = allCars.SelectMany(x => x.CarNames)
.GroupBy(x => x, x => x, (key, x) => new
{
CarName = key,
Count = x.Count()
})
.ToList();
foreach (var carDistribution in carDistributions)
{
Console.WriteLine(carDistribution.CarName + " " + carDistribution.Count);
}
}
}
public class Car
{
[JsonProperty("Car")]
public List<string> CarNames { get; set; }
}
输出:
Honda Civic 3
Toyota Camry 2
BMW 760 3
Mercedes S 1
Smart Car 1
Honda Odyssey 2
Tesla X 2
答案 1 :(得分:0)
首先使用json2csharp或PasteSpecial选项创建用于json解析的模型。
您可以在编辑->选择性粘贴-> JSON作为类粘贴JSON 中找到PasteSpecial选项。
这将为您提供正确的模型来解析json字符串,即
public class Car
{
public List<string> car { get; set; }
}
现在,当您使用代码进行Json反序列化时,请使用相同的代码。
List<Car> allCars = JsonConvert.DeserializeObject<List<Car>>(sJSON);
使用Linq SelectMany()
和where()
,您可以根据其名称获得所有汽车记录,现在使用简单的Count()
,您将从Json Array中获得每辆汽车的数量
int count = allCars.SelectMany(x => x.car).Where(x => x == "Honda Civic").Count(); // It will return 3 as a result
答案 2 :(得分:0)
此JSON结果的本机数据类型为dotnet ef database update 20190524150901_initialll
。您可以直接使用以下方法进行解析:
List<Dictionary<string, string[]>>
然后您可以创建一些函数来搜索该数据:
var cars = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Dictionary<string, string[]>>>(json);
如果您要将JSON中的数据重新组织到Households中,则可以执行以下操作:
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));
}
具有修改后的搜索功能:
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));
}
恕我直言,您对Newtonsoft的反序列化类应尽可能简单。 Newtonsoft功能强大,在反序列化过程中您可以做很多事情,但是它越简单,如果将来需要更改数据的结构,修改就越容易。反序列化后的映射功能是将数据转换为对应用程序有用的东西。我认为这是一个好的SoC原则。
奖励回合
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
产生如下输出:
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));
}
}