Convert a result set to another with a different structure?

I have 2 classes as shown:

public class Route {
    public int node;
    public int link;
    public int weight;
}

      

The data in the node list will look like this:

node    link    weight
----------------------
1       A       0
1       B       10
2       C       5
2       D       8
2       E       12

      

Second class:

public class Segment{
    public int node;
    public String linkFrom, linkTo;
    public int weight;
}

      

Is there an elegant solution to transform the above list into a new segment list that looks like this?

node    linkfrom    linkto    weight
------------------------------------
1       A           B         10
2       C           E         25

      

The node list is converted to a segment list grouping

per node. The weight is the sum of the weights of these links in the node, a linkFrom

is the first link in the node, and linkTo

is the last link in the node before the group was changed.

+3


source to share


3 answers


Assuming for a specific node, for different links, each link will have different nodes. You can try adding a type function transform

and a custom comparator for your route class (or compareTo

and make it realistic ~ comparable to iterface) to compare routes by weight, I would go with a custom comparator because it doesn Look like comparison with weight is a natural comparison of routes ...

The code would be something like -

static class WeightComparator implements Comparator<Route>
 {
     public int compare(Route o1 , Route o2) {
         if(o1.weight > o2.weight) {
             return 1;
         }
         else if(o1.weight < o2.weight) {
             return -1;
         }
         return 1;
     }

public class Segment{
    public int node;
    public String linkFrom, linkTo;
    public int weight;

    public void transform(int node, List<Route> routes) {
        List<Route> routesWithNode = new ArrayList<Route>();
        for(Route route : routes) {
            if(route.node == node) {
                routesWithNode.add(route);
            }
        }
        Collections.sort(routesWithNode , new WeightComparator());
        this.node = node;
        this.linkFrom = routesWithNode.get(0).link;
        this.linkTo = routeWithNode.get(routesWithNode.length - 1).link;
        int tweight = 0;
        for(Route r: routeWithNode) {
            tweight = tweight + r.weight;
        }
        this.weight = tweight;
    }
}

      



Then in your main or wherever you need to create these segments, for each unique node in the route list, you can do -

for uniqueNode in routeList:
    segmentList.add(new Segment().transform(uniqueuNode, routeList)

      

Please note that above is not java code, its pseudo code, you need to write complete code.

0


source


Add a new class called Convert

public class Convert{
  public Route firstRoute;
  public Route lastRoute;
  public Segment segment;

  public Convert(){
   this.segment = new Segment();
 }
}

      

Then create a map of all routes to identify the first member in the list of all routes.

public HashMap<Integer,Route> map = new HashMap<>();

      

Create Convert list to store converted list data



public List<Convert> convertedList = new ArrayList<>();

      

Then iterations

for(int i=0;i<routes.size();i++){
    Route route = routes.get(i);
    Convert convert = new Convert();
    if(map.get(route.node)!=null){
        convert.lastRoute = route;
        convert.segment.linkTo=String.valueOf(route.link);
    }else{
       map.put(route.node);
       convert.firstRoute = route;
       convert.segment.node=route.node;
       convert.segment.linkFrom=String.valueOf(route.link);
    }
    convert.segment.weight+=route.weight;
     convertedList.add(convert);
}


for(Convert con:convertedList)[
//Print in the required format
}

      

I made the assumption that you want the last link in the route list to always be as linkTo in the segment.

0


source


I created below code. It's pretty rude.

public void convert() {
        // List to hole segments
        ArrayList<Segment> segments = new ArrayList<Segment>();
        // List holding routes
        ArrayList<Route> routes = createRoutes();
        // Node id
        int startRouteNode = routes.get(0).node;
        // Start Link
        String startLink = null;
        // Link in previous node traversed
        String previousLink = null;
        // Weight
        int weight = 0;
        for (Route route : routes) {
            // If current route is on the same node as previous one
            if (startRouteNode == route.node) {
                if (startLink == null)
                    startLink = route.link;

                previousLink = route.link;
                weight += route.weight;
            } else {
                // If current route is not on previous node
                segments.add(new Segment(startRouteNode, startLink,
                        previousLink, weight));
                startRouteNode = route.node;
                startLink = previousLink;
                weight = route.weight;
            }
        }
        // Add last segment in segment list
        segments.add(new Segment(startRouteNode, startLink, previousLink,
                weight));
        System.out.println(segments);
    }

    ArrayList<Route> createRoutes() {
        ArrayList<Route> arraylist = new ArrayList<Route>();
        arraylist.add(new Route(1, "A", 0));
        arraylist.add(new Route(1, "B", 10));
        arraylist.add(new Route(2, "C", 5));
        arraylist.add(new Route(2, "D", 8));
        arraylist.add(new Route(2, "E", 12));

        return arraylist;
    }

      

0


source







All Articles