Home > Blockchain >  How to compare 'list of string' with 'enum string values' to return maximum matc
How to compare 'list of string' with 'enum string values' to return maximum matc

Time:12-02

The current code send List<String> but returns Enum if all values matches

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public enum Rara {
    MA_ON("ST"),
    MA_MAN("ST", "YS"),
    MA_IP("ST", "YS", "IC"),
    CODE("RC");

    Rara(String... codes) {
        this.codes = List.of(codes);
    }

    private List<String> codes;

    public static Optional<Rara> getValue(List<String> values){
        return Arrays.stream(values())
                .filter(rara -> rara.codes.containsAll(values))
                .findFirst();
    }
}

public class Main {
  public static void main(String args[]){
    System.out.println(Rara.getValue(Arrays.asList("ST", "YS")));  
          // Optional[MA_MAN]

    System.out.println(Rara.getValue(Arrays.asList("ST")));  
          // Optional[MA_ON]
  }
}

But now requirements are if we get List as then max match enum should be returned

System.out.println(Rara.getValue(Arrays.asList("ST", "YS", "IC", "BLABLA")));  
 //Should return MA_IP
System.out.println(Rara.getValue(Arrays.asList("ST", "Bla", "Blabla", "BLABLA")));  
//Should return MA_ON

Note: IN case of ST & RC or any conflicting We need to pick the first one. (Like ST, RC we can pick MA_ON)

can anyone suggest how to achieve in same enum in getValue? (In place of containsALL if i add contains then it doesn't work. Not sure if it requires some maxmatch etc)

CodePudding user response:

If I understood your problem correctly all you need is to know

  • how many common strings has codes and values (for each enum)
  • filter out those with no common elements
  • pick one with maximum amount of common elements (or in case of many maxes first one from them)

To simplify our job we can create helper method to find only common elements in two lists. It can look like (I am assuming your Lists will have only unique elements)

private static List<String> commonElements(List<String> list1, List<String> list2) {
    List<String> common = new ArrayList<>(list1); // to avoid modifying `list1`
    common.retainAll(list2); // leaves in `common` only elements from `list2`
    return common;
}

With this we can

  • map each enum to pair containing enum, amountOfCommonElements (we can use Map.entry to create pairs),
  • filter pairs where amountOfCommonElements is 0,
  • pick pair with max amountOfCommonElements
  • get from that pair only enum.

Demo:

enum Rara {
    MA_ON("ST"),
    MA_MAN("ST", "YS"),
    MA_IP("ST", "YS", "IC"),
    CODE("RC");

    Rara(String... codes) {
        this.codes = List.of(codes);
    }

    private List<String> codes;

    private static List<String> commonElements(List<String> list1, List<String> list2) {
        List<String> common = new ArrayList<>(list1); // to avoid modifying `list1`
        common.retainAll(list2); // leaves in `common` only elements from `list2`
        return common;
    }

    public static Optional<Rara> getValue(List<String> values){
        return Arrays.stream(values())
                .map(en -> Map.entry(en, commonElements(en.codes, values).size()))
                .filter(entry -> entry.getValue()>0)
                .max(Comparator.comparing(Map.Entry::getValue))
                .map(Map.Entry::getKey);
    }

}

 class Main {
    public static void main(String args[]){
        System.out.println(Rara.getValue(Arrays.asList("ST", "YS")));
        // Optional[MA_MAN]

        System.out.println(Rara.getValue(Arrays.asList("ST")));
        // Optional[MA_ON]

        System.out.println(Rara.getValue(Arrays.asList("ST", "RC")));
        // Optional[MA_ON]

        System.out.println(Rara.getValue(Arrays.asList("STB", "RCC")));
        //Optional.empty
    }
}
  • Related