Variable can not be passed into for loop

核能气质少年 提交于 2019-12-13 20:16:09

问题


I have a data frame including sender (id, int), receiver(id, int), communication times (int).

A B C
1 5 10
1 6 20
1 7 20
1 8 11

my goal is to find the max communication times and return as 1 6,20 (format as A B,C) Since A1, B6 and A1, B7 both have max communication times 20, I just need to keep the smallest B id number.

In map step, I already separated A as key, (B,C) as value.

So far I can return the output with A and max C, but I have trouble to return the B value. My code below cannot change the min_Receiver, how can I fix this issue?

public static class IntSumReducer
extends Reducer<Text,Text,Text,Text> {
    //private IntWritable result = new IntWritable();

    public void reduce(Text key, Iterable<Text> values,
                       Context context
                       ) throws IOException, InterruptedException {
        int max_val = 0;
    int val_str = 0;
    int val_str_1 = 0;
    int min_Receiver = Integer.MAX_VALUE;
    int tempReceiver = 0;
        for (Text val : values) {
    String[] compositeString = val.toString().split(",");
    val_str = Integer.parseInt(compositeString[1]);
    //tempReceiver = Integer.parseInt(compositeString[0]);
            if( val_str>max_val) {
                max_val = val_str;

    }


    }

   for (Text val_1 : values){
    String[] compositeString = val_1.toString().split(",");
    tempReceiver = Integer.parseInt(compositeString[0]);        
    val_str_1 = Integer.parseInt(compositeString[1]);

    if (val_str_1 == max_val && tempReceiver < min_Receiver)
        {
           min_Receiver =tempReceiver;
        }

    }

        //result.set(max_val);
        context.write(key, new Text(min_Receiver + "," + max_val));}}

Expect output would be

1 6,20

the actual output is

1 2147483647,20

In the map, I already separated A as key, and B,C as value. So the compositeString includes two variables. The format in value is B,C.


回答1:


Depending on what your delimeter is

use a line like this to get the Text with the max time

Optional<Text> answer = StreamSupport.stream(values.spliterator(),false)  //all this does is get you a stream of Text
.max(Comparator.comparingInt(s->getComTime(s))); // return the object that evaluates to the max value if one exists

along with creating a method that gets the Communication time from a string/Text like this:

private static int getComTime(Text line){
    String[] vals = line.toString().split(",");
    return  Integer.parseInt(vals[2]);
}

the boolean option for the .stream() is if you want sequential=false or parallel =true .... if your delimiter is different or the object is a little different you may need to adjust getComTime but this should be pretty close to right.

get an Optional if you want to handle it that way.

then you can do

if(answer.isPresent()){/* got an answer do something with it */}

***Sry i did most of this with Strings instead of Text but this is updated let me know if there are any issues.



来源:https://stackoverflow.com/questions/58496984/variable-can-not-be-passed-into-for-loop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!