0

I'm analyzing a set of structured data and I have an array of similar key names

(Eg: GENDER_ATTRIBUTE = {sex, gender})

Then I have a dataset that can might have one key from the previous array as a key and I need to get the value of that.

Eg:

name: ABC,
address: XYZ,
gender: F

OR

name: ABC,
address: XYZ,
sex: F

At the end I will need to get a result such as GENDER_ATTRIBUTE = F.

I can definitely use an iterative approach to check against each item of the array against the dataset, but I want to find out if there is a better way to achieve this.

UPDATE

Currently the dataset is implemented as a LinkedHashMap and the attribute names are stored in a String array.

S.Dan
  • 1,826
  • 5
  • 28
  • 55

2 Answers2

2

For the example above, I can't think of a better way than iteratively checking. You'd have to do one comparison for each possible key, so the amount of time taken to find your value is going to be O(n) where n is the number of possible keys. If n is "small" - for example, n=2 as above, there's nothing that's going to improve over that.

If n, the number of possible keys, grows large, you could use a map to improve lookup time, namely: build an additional map of keys to their unique attribute. In this case, sex and gender would both map to GENDER_ATTRIBUTE.

  1. get input (key:value) - in your example value is F and key could be sex or gender
  2. look in key:attribute map to find the attribute for that key - in your example GENDER_ATTRIBUTE
  3. return attribute:value - in your example GENDER_ATTRIBUTE:F

While in terms of time-complexity this only makes sense if there are many different possible keys, it could improve readability considerably even with a modest number of keys.

MyStackRunnethOver
  • 4,872
  • 2
  • 28
  • 42
1

I assume you are trying to use something like single standard key for a map that can be represented by multiple different labels. Like in your example: you expect to use GENDER_ATTRIBUTE as a key that is equal to sex and gender labels, right?

If so, consider following example:

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

final class MapTest {

    private static final Map<String, List<String>> similarKeys = new HashMap<String, List<String>>() {{
        put("GENDER_ATTRIBUTE", Arrays.asList("sex", "gender"));
    }};

    public static void main(String[] args) {

        final Map<String, Object> dataSet1 = new HashMap<String, Object>() {{
            put("name", "ABC");
            put("address", "XYZ");
            put("gender", "F");
        }};

        final Map<String, Object> dataSet2 = new HashMap<String, Object>() {{
            put("name", "ABC");
            put("address", "XYZ");
            put("sex", "F");
        }};

        System.out.println("GENDER_ATTRIBUTE from dataSet1 is " + getValueForKey("GENDER_ATTRIBUTE", dataSet1));
        System.out.println("GENDER_ATTRIBUTE from dataSet2 is " + getValueForKey("GENDER_ATTRIBUTE", dataSet1));
    }

    private static Object getValueForKey(String key, Map<String, Object> dataSet) {
        final String finalKey = similarKeys.getOrDefault(key, Collections.emptyList())
                .stream()
                .filter(it -> dataSet.keySet().contains(it))
                .findFirst()
                .orElse(key);

        return dataSet.get(finalKey);
    }
}

What happens here is that firstly we define similarKeys mapping - a map that associates single key with multiple different labels. Then the whole logic is encapsulated in getValueForKey(String key, Map<String, Object> dataSet). This method checks if passed key is a final key or is it pointing to a one similar keys. If so then it checks which key can be found in given dataset. Please let me know if this is what you expect. The question was not precise so I had to make some assumptions to prepare this answer. I hope it helps.

Szymon Stepniak
  • 40,216
  • 10
  • 104
  • 131