클로이의 데이터 여행기

[JAVA] 동일한 값(데이터) 기준으로 결합(합치기) 본문

JAVA

[JAVA] 동일한 값(데이터) 기준으로 결합(합치기)

징느K 2019. 1. 17. 20:16


이번 포스팅에서는 '동일한 값(데이터) 기준으로 데이터를 결합'하는 소스를 살펴보려고 합니다.


아래와 같이 [그림1]과 같은 데이터를 [그림2]처럼 결합하고자 할 때가 있는데요.


           

              

[그림1]                               [그림2]


엑셀에서 작업시에는 필터 기능을 사용하여 직급별로 sorting 후 복사 붙여넣기 하곤 했습니다.

따로 코딩없이 작업이 가능하지만, 분류(예를들면 그림에서는 '직급')값이 엄청나게 다양하다면 많은 시간이 든다는 단점이 있었습니다.


그래서 효율적인 업무진행을 위해 아래와 같이 

동일한 key값을 기준으로 원하는 필드의 내용을 리스트로 담아 결합하는 소스를 작성하였습니다.


소스 사용 시에는, 아래의 값들을 main에 넣어주시면 됩니다.

- 합치고자 하는 파일명과 경로 : rawFile 
- 합치고자 하는 열이 몇 번째 인지 : merNum 
- 합치는 기준이 되는 열이 몇 번째 인지 : keyNum 
- 작업파일의 필드가 몇 개인지 : idxCnt
- 결과 파일명과 경로: resultFile 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package listJoin;
 
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.ArrayList;
 
    public class ListJoin {
        
        // 파일을 읽어서 변수에 담음
        public static String getLine(String filename) {
 
            String lineList = "";
            File file = new File(filename);
 
            try {
                BufferedReader inFiles
                        = new BufferedReader(new InputStreamReader(new FileInputStream(file.getAbsolutePath()), "UTF8"));
 
                String line = "";
                
                while ((line = inFiles.readLine()) != null) {
                    if (line.trim().length() > 0) {
                        lineList += line + "\n";
                    }
                }
                inFiles.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return lineList;
        }
        
        // 파일을 줄바꿈(\n)으로 나누어 리스트에 담음
        public static String[] setList(String filename) {
            String sent = getLine(filename).toLowerCase();
            String[] arr = sent.split("\n");
 
            return arr;
        }
        
        // key값이 없다면 새로 list형태의 value를 추가
        // key값이 이미 있다면 list형태의 value를 불러와서 list에 추가
        public static HashMap<String, ArrayList<String>> joinDic(String[] arr, int keyIdx, int merIdx, int idxCnt) {
            HashMap<String, ArrayList<String>> dic = new HashMap<String, ArrayList<String>>();
            // 맨 윗줄에 필드 설명이 있다면 1부터, 없다면 0부터 설정
            // sample파일의 경우 설명이 있으므로 i가 1부터 시작
            for (int i = 1; i < arr.length; i++) {
                String[] line = arr[i].split("\t");
                
                //여러개의 필드 중 합치고자 하는 기준
                String key = line[keyIdx];
 
                // 합치는 값이 없을 때, 무시하기
                if(line.length!=idxCnt)
                    continue;
 
                ArrayList<String> list = new ArrayList<String>();
                if (line[1].equals("")) {
                    continue;
                } else {
                    if (dic.containsKey(key)) {
                        // 이미 해당 key가 맵에 있을 때에는 value를 불러온 뒤 넣음
                        list = dic.get(key);
                        list.add(line[merIdx]);
                    } else {
                        // 맵에 key가 없다면 새로 value를 추가
                        list.add(line[merIdx]);
                    }
                    dic.put(key, list);
                }
            }
            System.out.println("===========직급별 직원이름===========");
            for (String key : dic.keySet()) {
                System.out.println(key+" => " + dic.get(key) );
            }
            return dic;
        }
 
        public static void writeFile(HashMap<String, ArrayList<String>> dicdic, String fileName) {
 
            try {
                File file = new File(fileName);
                BufferedWriter writer = new BufferedWriter(new FileWriter(file));
 
                if (file.isFile() && file.canWrite()) {
                    for (String key : dicdic.keySet()) {
                        writer.write(key + "," + dicdic.get(key) + "\n");
                    }
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
 
        public static void main(String[] args) {
            String rawFile = "C:/data/input/sample.txt"//합치고자 하는 파일명과 경로
            int keyNum = 1 ; // 합칠때 기준이 되는 필드의 번호에서 -1
            int merNum = 0 ; // 합치고자 하는 필드의 번호에서-1
            int idxCnt = 2 ; // 작업 파일의 필드 수
            String resultFile = "C:/data/output/result_listjoin_sample.txt"//최종결과  파일명과 경로
            
            getLine(rawFile);  
            String[] lineArr = setList(rawFile);
            HashMap<String, ArrayList<String>> mergeDic = joinDic(lineArr,keyNum,merNum,idxCnt);
            writeFile(mergeDic, resultFile );
            
        }
    }
cs


위의 소스를 구동해보면 아래와 같이 결과가 출력됩니다.




이상입니다.

감사합니다.


Comments