3

我有類型的.csv文件2D布爾數組:Java創建從表中的數據

Event      Participant 
ConferenceA    John 
ConferenceA    Joe 
ConferenceA    Mary  
ConferenceB    John 
ConferenceB    Ted 
ConferenceC    Jessica 

我想創建以下格式的2D布爾矩陣:

Event  John Joe Mary Ted Jessica 
ConferenceA 1  1 1  0 0 
ConferenceB 1  0 0  1 0 
ConferenceC 0  0 0  0 1 

我開始閱讀的CSV,並用它來初始化類型的ArrayList:

AttendaceRecord(String title, String employee) 

我怎樣才能通過此ArrayList迭代創建布爾矩陣像上面的Java中的一個?

+1

這個CSV可以有任意數量的會議和/或參與者的? – Andy

+0

將此插入到ArrayList中時,您是否在維護其他變量,例如您擁有多少個不同的員工或事件? –

+1

爲什麼不使用「Map」?關鍵是會議,價值將成爲參與者?它是否必須是一個'ArrayList'?這對你來說會容易得多。 – Andy

回答

1

這是最簡單的方法我可以爲你想。這個答案當然可以改進或以完全不同的方式完成。我採取這種方法,因爲你提到你不完全熟悉Map(我也猜測Set)。無論如何,讓我們潛入。

在您的AttendanceRecord類中,您將需要以下實例變量:兩個LinkedHashSet和一個LinkedHashMapLinkedHashSet#1將存儲所有會議,LinkedHashSet#2將存儲所有參與者。 LinkedHashMap將會議存儲爲keys和參與者列表values。這一點的原因將在一分鐘內清楚。我會先解釋你爲什麼需要LinkedHashSet。在你的二維數組LinkedHashSet通知

目的,行(會議)和列(參與者)的順序排列,他們閱讀。不僅如此,從文件中讀取的所有副本都沒有了。爲了保持順序並消除重複,LinkedHashSet完美適合這一目的。然後,我們將通過它們的數組表示在二維數組的行位置和列位置與每個LinkedHashSet之間具有一對一的關係。例如,我們使用來自ConferenceAJhonJhon將位於參與者Set的陣列表示中的位置0處,並且ConferenceA將位於會議Set的陣列表示中的位置0處。不僅如此,每個數組的大小將被用來確定你的二維數組的大小(2darray [conferenceArrayLength] [participantArrayLength])

目的的LinkedHashMap中的

我們需要LinkedHashMap保存元素排序(因此Linked)。元素將像這樣在內部存儲。

ConferenceA :Jhon Joe Mary 
ConferenceB :Jhon Ted 
ConferenceC :Jessica 

我們將隨後通過數據結構迭代和發送每個keyvalue對來返回來自每個陣列的各元素從各LinkedHashSet返回的位置的函數。隨着每個行和列的位置被返回,我們將在2d數組中添加1到那個位置。

注意:我使用整數數組作爲我的例子,根據需要替換。

AttendanceRecord.java

public class AttendanceRecord { 

    private Map<String, ArrayList> attendanceRecordMap = new LinkedHashMap<String, ArrayList>(); 
    private Set<String> participants = new LinkedHashSet<String>(); 
    private Set<String> conferences = new LinkedHashSet<String>(); 

    public AttendanceRecord() { 
    } 

    public Map<String, ArrayList> getAttendanceRecordMap() { 
     return attendanceRecordMap; 
    } 

    public Object[] getParticipantsArray() { 
     return participants.toArray(); 
    } 

    public Object[] getConferencesArray() { 

     return conferences.toArray(); 
    } 

    public void addToRecord(String title, String employee) { 

     conferences.add(title); 
     participants.add(employee); 

     if (attendanceRecordMap.containsKey(title)) { 
      ArrayList<String> tempList = attendanceRecordMap.get(title); 
      tempList.add(employee); 
     } else { 
      ArrayList<String> attendees = new ArrayList<String>(); 
      attendees.add(employee); 
      attendanceRecordMap.put(title, attendees); 
     } 
    } 
} 

Test.java

public class Test { 

    public static void main(String[] args) { 

     AttendanceRecord attendanceRecord = new AttendanceRecord(); 

     //There are hardcoded. You will have to substitute with your code 
     //when you read the file 
     attendanceRecord.addToRecord("ConferenceA", "Jhon"); 
     attendanceRecord.addToRecord("ConferenceA", "Joe"); 
     attendanceRecord.addToRecord("ConferenceA", "Mary"); 
     attendanceRecord.addToRecord("ConferenceB", "Jhon"); 
     attendanceRecord.addToRecord("ConferenceB", "Ted"); 
     attendanceRecord.addToRecord("ConferenceC", "Jessica"); 

     int[][] jaccardArray = new int[attendanceRecord.getConferencesArray().length][attendanceRecord.getParticipantsArray().length]; 
     setUp2dArray(jaccardArray, attendanceRecord); 
     print2dArray(jaccardArray); 
    } 

    public static void setUp2dArray(int[][] jaccardArray, AttendanceRecord record) { 
     Map<String, ArrayList> recordMap = record.getAttendanceRecordMap(); 

     for (String key : recordMap.keySet()) { 
      ArrayList<String> attendees = recordMap.get(key); 

      for (String attendee : attendees) { 
       int row = findConferencePosition(key, record.getConferencesArray()); 
       int column = findParticipantPosition(attendee, record.getParticipantsArray()); 
       System.out.println("Row inside " + row + "Col inside " + column); 
       jaccardArray[row][column] = 1; 
      } 
     } 
    } 

    public static void print2dArray(int[][] jaccardArray) { 
     for (int i = 0; i < jaccardArray.length; i++) { 
      for (int j = 0; j < jaccardArray[i].length; j++) { 
       System.out.print(jaccardArray[i][j]); 
      } 
      System.out.println(); 
     } 
    } 

    public static int findParticipantPosition(String employee, Object[] participantArray) { 
     int position = -1; 

     for (int i = 0; i < participantArray.length; i++) { 
      if (employee.equals(participantArray[i].toString())) { 
       position = i; 
       break; 
      } 
     } 
     return position; 
    } 

    public static int findConferencePosition(String employee, Object[] conferenceArray) { 
     int position = -1; 

     for (int i = 0; i < conferenceArray.length; i++) { 
      if (employee.equals(conferenceArray[i])) { 
       position = i; 
       break; 
      } 
     } 
     return position; 
    } 
} 
+0

真棒解釋和演示新的'地圖'和'設置'的人!我相信其他的解釋也可以起作用,但這是一個非常明確和很好解釋的實現。謝謝 –

+0

不客氣。對不起,給出了完整的答案(我不認爲你介意)。我非常喜歡那個問題,並且我被帶走了。祝你好運 :) – Andy

1

基本上,你會想通過搜索你的輸入字符串來找到每個名稱(String.contains)並設置每個字段名稱的布爾數組。

然後,您將製作一個布爾數組(或列表,無論)的數組。

然後,您只需對它們進行排序,尋找T/F並打印相應的消息。

我包括一些非常粗略的僞代碼,假設我正確地理解你的問題。

// For first row 
List labelStrings[]; 

labelStrings = {"Event", "John", "Joe", "Mary", "Ted", "Jessica"}; 

// For the matrix data 

// List to iterate horizontally EDIT: Made boolean! 
List<Boolean> strList= new ArrayList()<List>; 
// List to iterate vertically 
List<List> = listList new ArrayList()<List>; 

/* for all the entries in AttendanceRecord (watch your spelling, OP) 
    for all data sets mapping title to employee 
     add the row data to strList[entry_num] */ 

for (int i = 0; i < listList.size()-1; i++) 
    for (int j = 0; j < labelStrings.size()-1; j++) 
    { 
     if (i == 0) 
     System.out.println(strList[j] + "\t\n\n"); 
     else 
     { 
     // print listLists[i][j] 
     } 
    // iterate row by row (for each horizontal entry in the column of entries) 
    } 

對不起,我只是通讀現在的意見。

您一定希望以易於迭代的方式排列數據。既然你有一個固定的表大小,你可以爲每個條目硬編碼一個布爾數組,然後在驗證時打印它們映射到事件,如輸入字符串中所示。

+0

我不認爲桌子的大小是固定的。這就是爲什麼我要求他確定。再一次,從他的職位來看,我不清楚。 – Andy

+1

這不是一個難以解決的問題。我的意圖是爲OP提供有用的信息,幫助他走上正軌。這個線程總體上缺乏票數,有多少響應。 – jdero

+0

我知道,我不是在批評。 – Andy

1

嘗試創建包含

HashMap map = new HashMap<conferenceStr, HashMap<nameStr, int>>() 

哈希地圖,讓您輕鬆的ArrayList迭代,你可以這樣做

innerMap = map.get(conferenceStr) 
innerMap.put(nameStr, 1) 

當然你需要一些初始化的邏輯,就像你可以檢查如果innerMap.get(nameStr)存在,如果不存在,遍歷每個內部映射和innerMap.put(nameStr,0)

此結構可用於生成最終的2D布爾可以矩陣。

擬訂編輯:

ArrayList<AttendanceRecord> attendanceList = new ArrayList<AttendanceRecord>(); 

// populate list with info from the csv (you implied you can do this) 

HashMap<String, HashMap<String, Integer>> map = new HashMap<String, HashMap<String, Integer>>(); 

//map to store every participant, this seems inefficient though 
HashMap<String, Integer>> participantMap = new HashMap<String, Integer>(); 

for (AttendanceRecord record : attendanceList) { 
    String title = record.getTitle(); 
    String employee = record.getEmployee(); 

    participantMap.put(employee, 0); 


    HashMap<String, Integer> innerMap = map.get(title); 
    if (innerMap == null) { 
    innerMap = new HashMap<String, Integer>(); 

    } 
    innerMap.put(employee, 1); 
} 

//now we have all the data we need, it's just about how you want to format it 

例如,如果你想只打印出一張類似的表格,你可以通過地圖中的每個元素重複這樣做:

for (HashMap<String, Integer> innerMap : map.values()) { 
    for (String employee : participantMap.values()) { 

    if (innerMap.get(employee)) { 
     //print 1 
    } 
    else 
     //print 0 
    } 
} 
+1

不確定OP技能水平,但通過他的問題來判斷,這種方法可能有點太過分(OP沒有任何意圖只是試圖提供幫助)。可能更容易分階段打破他,你不覺得嗎?而不是在'Map'中有'Map'。我仍然喜歡這個。 – Andy

+0

@Robert你能詳細解釋一下嗎? –

+0

添加了一些代碼闡述,讓我知道如果有什麼困惑 –