JSON结构转换技术求助:现有JSON数组转目标结构问题咨询
Solution to Group Shops by Province and City
Hey there! It looks like you want to convert your flat list of shop data into a hierarchical structure grouped first by province, then by city. Let's walk through a couple of solid ways to do this in JavaScript.
Basic Approach with Array.reduce() and find()
This is straightforward and easy to read, perfect for smaller datasets:
var data = [ {"province":"PROVINCEA","city":"CITYA","shopName":"shop name1","address":"shop address1","tel":"phone number1"}, {"province":"PROVINCEA","city":"CITYA","shopName":"shop name2","address":"shop address2","tel":"phone number2"}, {"province":"PROVINCEA","city":"CITYB","shopName":"shop name3","address":"shop address3","tel":"phone number3"}, {"province":"PROVINCEA","city":"CITYB","shopName":"shop name4","address":"shop address4","tel":"phone number4"} ]; const transformedData = data.reduce((acc, shop) => { // Check if the province already exists in our accumulator let provinceEntry = acc.find(item => item.province === shop.province); if (!provinceEntry) { // If not, create a new province entry and add it to the array provinceEntry = { province: shop.province, cities: [] }; acc.push(provinceEntry); } // Now check if the city exists under this province let cityEntry = provinceEntry.cities.find(cityItem => cityItem.city === shop.city); if (!cityEntry) { // Create a new city entry if it doesn't exist cityEntry = { city: shop.city, shops: [] }; provinceEntry.cities.push(cityEntry); } // Add the shop details to the city's shop list (we skip province/city since they're in parent levels) cityEntry.shops.push({ shopName: shop.shopName, address: shop.address, tel: shop.tel }); return acc; }, []); console.log(transformedData);
How this works:
- We use
reduce()to build our structure incrementally as we loop through each shop. - For every shop, we first check if its province is already in our result array. If not, we create a new province object with an empty
citiesarray. - Next, we check if the shop's city exists under that province. If not, we create a city object with an empty
shopsarray. - Finally, we add the shop's details to the corresponding city's
shopsarray.
Optimized Approach for Large Datasets
If you're working with a big list of shops, using object maps for lookups will be faster (O(1) instead of O(n) for each find() call):
const transformedData = Object.values(data.reduce((acc, shop) => { // Create a province entry if it doesn't exist if (!acc[shop.province]) { acc[shop.province] = { province: shop.province, cities: {} }; } const provinceEntry = acc[shop.province]; // Create a city entry under the province if it doesn't exist if (!provinceEntry.cities[shop.city]) { provinceEntry.cities[shop.city] = { city: shop.city, shops: [] }; } const cityEntry = provinceEntry.cities[shop.city]; // Add the shop to the city's list cityEntry.shops.push({ shopName: shop.shopName, address: shop.address, tel: shop.tel }); return acc; }, {})).map(province => { // Convert the cities object to an array to match our desired structure province.cities = Object.values(province.cities); return province; });
Key optimizations here:
- We use objects to map province names and city names to their respective entries, which makes checking existence instant.
- After building the map structure, we convert it back to arrays using
Object.values()to get the final hierarchical array format.
Both approaches will give you a structure like this:
[ { "province": "PROVINCEA", "cities": [ { "city": "CITYA", "shops": [ {"shopName":"shop name1","address":"shop address1","tel":"phone number1"}, {"shopName":"shop name2","address":"shop address2","tel":"phone number2"} ] }, { "city": "CITYB", "shops": [ {"shopName":"shop name3","address":"shop address3","tel":"phone number3"}, {"shopName":"shop name4","address":"shop address4","tel":"phone number4"} ] } ] } ]
内容的提问来源于stack exchange,提问作者Bill
相关产品推荐
相关产品推荐

