Converting a JSON format with JavaScript

As the data for a simple online store is extracted from a headless CMS, it is structured in the following format:

[
    {
        "id": 12312,
        "storeName": "Store1",
        "googleMapsUrl": "https://example1.com",
        "country": "Australia",
        "state": "New South Wales"
    },
    {
        "id": 12313,
        "storeName": "Store2",
        "googleMapsUrl": "https://example2.com",
        "country": "Australia",
        "state": "Queensland"
    },
    {
        "id": 12314,
        "storeName": "Store3",
        "googleMapsUrl": "https://example3.com",
        "country": "Indonesia",
        "state": "Java"
    },

]

This data will be utilized to create a user-friendly store locator that is categorized by Country followed by State.

No modifications can be made on the CMS system. Therefore, I am seeking recommendations on how to iterate through this flat data structure and arrange it according to country and state.

UPDATE: An attempt was made to isolate unique countries using the following code snippet:

let newArray = this.$page.stores.edges.map(item =>{
let newObj = {};
newObj[item.node.country] = item.node.country;
newObj[item.node.country.state] = item.node.state;
console.log(newObj)
return newObj;
      });

However, it remains unclear on how to proceed further to link these countries with respective states and eventually the stores themselves.

Answer №1

Arranged by country and state.

var data = [{
    "id": 12314,
    "storeName": "Store3",
    "googleMapsUrl": "https://example3.com",
    "country": "Indonesia",
    "state": "Java"
  },
  {
    "id": 12315,
    "storeName": "Store4",
    "googleMapsUrl": "https://example4.com",
    "country": "Australia",
    "state": "Queensland"
  },
  {
    "id": 12312,
    "storeName": "Store1",
    "googleMapsUrl": "https://example1.com",
    "country": "Australia",
    "state": "New South Wales"
  },
  {
    "id": 12313,
    "storeName": "Store2",
    "googleMapsUrl": "https://example2.com",
    "country": "Australia",
    "state": "Queensland"
  },
]
var stores = {};
var countries = new Set(data.map(item => item.country).sort());
countries.forEach(country => {
  var states = {};
  var items = data.filter(item => item.country == country);
  new Set(items.map(item => item.state).sort()).forEach(state => {
    states[state] = items.filter(item => item.state == state)
      .sort(item => item.state);
  });
  stores[country] = states;
});
console.log(stores['Australia']['Queensland']);

Answer №2

By simplifying the stores, you can create a country-state map as shown below.

{
  "Australia": {
    "states": [
      "New South Wales",
      "Queensland"
    ]
  },
  "Indonesia": {
    "states": [
      "Java"
    ]
  }
}

To emphasize sorting, I have rearranged the store data to make the sorting process more evident.

let stores = sortByCountryAndState(getData())
let locations = groupByCountryAndState(stores)

console.log(locations)

function sortByCountryAndState(data) {
  return data.sort((storeA, storeB) => {
    if (storeA == null) return 1
    if (storeB == null) return -1
    let diff = storeA.country.localeCompare(storeB.country)
    if (diff === 0) return storeA.state.localeCompare(storeB.state)
    return diff
  })
}

function groupByCountryAndState(data) {
  return data.reduce((countries, store, index) => {
    let country = countries[store.country] || {}
    return Object.assign(countries, {
      [store.country] : Object.assign(country, {
          states : pushAndSort(country.states || [], store.state)
        })
      })
  }, {})
}

function pushAndSort(arr, value) {
  if (arr.indexOf(value) === -1) arr.push(value)
  //return arr.sort() // Sorting is done before the grouping...
  return arr
}

function getData() {
  return [{
    "id": 12314,
    "storeName": "Store3",
    "googleMapsUrl": "https://example3.com",
    "country": "Indonesia",
    "state": "Java"
  }, {
    "id": 12313,
    "storeName": "Store2",
    "googleMapsUrl": "https://example2.com",
    "country": "Australia",
    "state": "Queensland"
  }, {
    "id": 12312,
    "storeName": "Store1",
    "googleMapsUrl": "https://example1.com",
    "country": "Australia",
    "state": "New South Wales"
  } ]
}
.as-console-wrapper { top: 0; max-height: 100% !important; }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Enhancing SEO Performance with React Server Components

Exploring the new topic of React Server Components, which has recently been released, how does it impact SEO compared to SSR/Next.js? Unlike Next.js and traditional SSR where components are rendered statically on the server, React Server Components are re ...

Request a HTML variable and send it to JavaScript

My latest project involves a Binary to Decimal Calculator that is now fully functional, but I am looking to integrate an HTML input into it. <html> <input placeholder="00000000" name="htmlinput"></input> <input id="clickMe" type="butt ...

When trying to upload a file through input using WebDriver, the process gets stuck once the sendKeys

WebElement uploadInput = browser.findElementByXPath("[correct_identifier]"); uploadInput.sendKeys(elementPath); The script successfully initiates the file upload process, however, the custom JavaScript loading screen persists and fails to disappear as exp ...

RXJS - Trigger a function based on a specific condition being fulfilled by a value emitted from an observable

I have created a search field with autocomplete functionality. By using an observable that monitors changes in the text field, I am able to trigger actions based on user input. this.term.valueChanges .debounceTime(300) .distinctUntilChange ...

Using JQuery to create an animated slideToggle effect for a multicolumn list

I have a large list where each li element has a width of 33%, resulting in 3 columns: computers monitors hi-fi sex-toys pancakes scissors Each column contains a hidden UL, which is revealed through slideToggle on click. JQuery $('.subCate ...

Steps to displaying a genuine Docx file within a Material CardMedia

Currently, I am facing an issue with positioning a docx file in my app. Interestingly, jpg and mp4 files are displaying correctly, but the docx file is not positioned as expected. If you want to try it out, simply open a doxc file. In the FileContentRend ...

Having trouble with submitting the code - need help resolving the issue

I'm facing an issue with my submit cancel code. The JavaScript code I implemented for preventing the submission function on my page isn't working as expected. While it does work to a certain extent, it's not fully functional. I am seeking a ...

What is the best way to design a regular expression that will only match up to 12 numbers?

Is there a way to construct a regular expression that will validate a string containing up to 12 digits only? Thank you! ...

Avoid being redirected to another page after submitting the form, instead remain on the current page

Unable to understand why this functionality is not working the way it is supposed to... In my ASP.NET MVC5 form, I have two buttons - "Add New Product" which allows users to temporarily save product data (not to the database) and input information on anot ...

JavaScript code for transitioning between a thumbnail and a full-width image header on a webpage

I am looking to create transitions in NextJs that involve a smooth shift from a thumbnail image to a full-screen header when clicking on a project from the home page. I prefer utilizing internal routing rather than React Router, but I am open to using that ...

Troubleshooting Issue 415: Adding and modifying database records through jQuery AJAX in ASP.NET 6.0 MVC Application

Implementing the Add/Edit functionality for categories in my project led me to utilize a modal (pop-up) to transfer data to the backend without refreshing the page. To achieve this seamless interaction, I opted for ajax integration. However, encountering a ...

Issue encountered when displaying various data options in the dropdown menus within a modal window

My goal is to display a modal when a button is clicked. The modal renders perfectly fine, but I am facing an issue with duplication of dropdowns inside the modal when the "add more" button is clicked. The main issues are: 1. Selecting the first option in ...

Trigger Javascript on 'Nearby' input from Html form

I have a JavaScript code that retrieves the latitude and longitude of users from their device for a local search. Although everything works correctly, I want to make sure the script is only executed if the user specifically selects "nearby" as the locatio ...

Directing to index.html using ExpressJS

JS, I am working on an express app that has various routes defined. However, I am facing an issue where if the router does not match any route, it displays index.html instead of redirecting to a specific route like '/*' as I expected. I am unsu ...

How can I make two Three-JS Objects simultaneously run and animate on a single webpage?

Is there a way to run multiple three.js animations simultaneously without canceling each other out? How can I troubleshoot why adding a second object stops the first object from animating? I would like to have more than one three.js script running in the s ...

Is there a way to make the React component automatically refresh upon clicking the search button?

Just starting out with React and JavaScript, I decided to experiment with accessing a public API. Here is the function I created: import { useState } from "react"; import CountrySWR from "./CountrySWR"; export default function SearchFo ...

The parameters 'event' and 'event' are not compatible with each other

I'm currently working on a page that involves submitting a form: import React from 'react'; import Form from 'react-bootstrap/Form'; import { useSignIn } from '../../hooks/Auth/useSignIn'; import { useHistory } from &apos ...

How can access to web pages be limited to only logged-in users using Node.js?

Currently, I am attempting to create a filter using tokens in order to limit access to certain pages for unauthenticated users on node.js 0.10. I have implemented a middleware as shown below: app.all( "/product/*" , handler); // will not match /product ...

Loop through associative array in PHP using JQuery

I have a PHP associative array and I am using JQuery AJAX to retrieve the result array. My issue arises when passing the result to jQuery and attempting to loop through and extract each Sequence, Percent, and Date. I need to store this extracted data in a ...

"Why is it that when using jQuery, the .fail method doesn't accept arguments to deliberately

I am attempting to utilize custom JSON encoded data after intentionally triggering an error on the server (throwing an error on purpose) during a jQuery AJAX request. I am confused as to what is going wrong, as the header is correct and the data is being ...