简体   繁体   中英

Re-indexing array from 0 in the string

How could I transform this structure in Java? (they are request parameters, so both of param:value are strings)

"country[0].town[11].name"="London"
"country[0].town[2].name"="Slough"
"country[2].town[3].name"="New York"
"country[3].name"="UK"

to sequential order without gaps like this:

"country[0].town[1].name"="London"
"country[0].town[0].name"="Slough"
"country[1].town[0].name"="New York"
"country[2].name"="UK"

The idea is that all country array elements would be from [0..x] without gaps. Then in each country the same rule should apply for towns.

I can sort the list of these parameters by Alpha-Numeric order so it can be assumed that they are sorted

The story why I might need this: I can create/delete country objects and towns in html form. If I create 2 countries and then delete the first one input parameter(index) of the remaining country would be 1 since 0 is deleted. when it goes to server side, this country is being mapped to list index 1 and for the first (index) it creates empty country object. It gives me problems and I thought I could rearrange the order of the input parameters so I could avoid "blank" list items automatically bound from request.

How I generate inputs:

when I delete town I delete inputs as well. So when I submit a form, whatever is in request parameters is bound to the java objects structure and what is missing is populated with the elements with default constructor.

I figured I'd try to get a solution working using regular expressions, since I'm so terrible at them. This will work if you sort them by lexical ordering first, provided that you don't have any countries without names.

public class RegexCountryParser {
    private static final Pattern townPattern    = Pattern
                                                    .compile("country\\[\\d*\\]\\.town\\[\\d*\\]\\.name");
    private static final Pattern countryPattern = Pattern.compile("country\\[\\d*\\]\\.name");
    private List<Country>        countries      = new ArrayList<>();

    public void parse(String param, String value) {
        Matcher countryMatcher = countryPattern.matcher(param);
        Matcher townMatcher = townPattern.matcher(param);
        if (countryMatcher.matches()) {
            countries.add(new Country(value));
        } else if (townMatcher.matches()) {
            countries.get(countries.size() - 1).addTown(new Town(value));
        } else {
            throw new IllegalArgumentException("Invalid request parameter");
        }
    }
}

public class Country {
    private String     name;
    private List<Town> towns;

    public Country(String name) {
        this.name = name;
        this.towns = new ArrayList<>();
    }

    public void addTown(Town town) {
        towns.add(town);
    }

    @Override
    public String toString() {
        return name + ": " + towns;
    }
}

public class Town {
    private String name;

    public Town(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return name;
    }
}

It wasn't until I started testing this that I realized you spelled country wrong. Also, this is just me being picky but I hate seeing lists that have non-plural names.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM