The first thing I would do, if I were you, would be to change the data structure so that the location would a hierarchical custom taxonomy where states were parent terms and cities their child terms.
Then you could create a custom taxonomy template for your location taxonomy. In this template you’d display list of child terms when the queried object is a parent term.
EDIT 3.9.2019
Here is a very basic example how to get the child terms in archive-{post_type}.php
template
// WP_Term object
$current_term = get_queried_object();
// maybe array of WP_Term objects
$children = get_terms( array(
'taxonomy' => $current_term->taxonomy,
'parent' => $current_term->term_id
) );
// If any child terms exists
if ( $children && ! is_wp_error( $children ) ) : ?>
<ul>
<?php foreach ( $children as $child_term ) : ?>
<li><?php echo esc_html( $child_term->name ); ?></li>
<?php endforeach; ?>
</ul>
<?php endif;
A good place to learn more about custom post types is the Plugin Handbook, https://developer.wordpress.org/plugins/post-types/working-with-custom-post-types/
And if you’re not very familiar with PHP yet, have a look at the PHP documentation Getting Started guide, https://www.php.net/manual/en/getting-started.php, or use your preferred search engine to find tutorials and beginner level courses.