0

I have data for a simple online store coming from a headless CMS. The data looks like this:

[
    {
        "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 used to make a simple store locator sorted by 1) Country and 2) State.

I'm unable to change anything on the CMS. Looking for suggested way to loop through this flat data object and list by country and state.

EDIT: I created this to extract the unique countries:

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;
      });

But again from there not sure how I would connect that to states and ultimately stores.

4
  • 1
    Hi, could you add what you're tried so far ? Commented Dec 20, 2019 at 14:09
  • 1
    Looks like a typical job for Array.sort: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented Dec 20, 2019 at 14:09
  • So what issue are you having? You have an array. You can loop over the array and get the info from the object. You have things like filter and map to help alter it. Commented Dec 20, 2019 at 14:15
  • I started by putting countries into an array. But wasn't quite sure how then to map states to the countries. Commented Dec 20, 2019 at 14:15

2 Answers 2

1

Ordered 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']);

Sign up to request clarification or add additional context in comments.

1 Comment

Removed this comment as figured out the usage.
1

You can build the following country-state map by reducing the stores.

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

I reversed the order of the store data so that the sorting will actually make a difference.

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; }

1 Comment

Thank you this is great. What about console.log so it also shows the array of stores per state?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.