2017-03-14 6 views
2

Ich habe eine JSON-Datei, die mehrere Textfelder mit doppelten Werten enthält. Beispiel:Entfernen Sie doppelte Textwerte aus allen JSON-Arrays mit Jackson

{ 
    "mName": "Carl Sanchez", 
    "mEmailID": "[email protected]", 
    "mPhoneNo": 7954041324, 

    "tutorTypes": [ 
     " Freelancer/Professional Tutor", 
     " Freelancer/Professional Tutor", 
     " Coaching Institute Teacher ", 
     " Corporate Professional ", 
     " Freelancer/Professional Tutor", 
     " Freelancer/Professional Tutor", 
     " Freelancer/Professional Tutor", 
     " Freelancer/Professional Tutor", 
     " Freelancer/Professional Tutor", 
     " Freelancer/Professional Tutor", 
     " Freelancer/Professional Tutor", 
     " Freelancer/Professional Tutor", 
     " Freelancer/Professional Tutor" 
    ], 
    "disciplines": [ 
     " Japanese", 
     " German ", 
     " Japanese", 
     " German ", 
     " Japanese", 
     " Hindi ", 
     " Japanese", 
     " French " 
    ] 
} 

Ich möchte doppelte Werte (die Textwerte) aus allen Arrays in der JSON-Quelle entfernen. Im obigen Beispiel würden Sie die doppelten Sprachen und Tutor-Typen aus den Arrays entfernen. Die gewünschte Ausgabe wäre die obige JSON-Quelle, wobei nur die doppelten Werte entfernt werden, wo immer dies möglich ist. Außerdem möchte ich den Code nicht an einen bestimmten JSON-Feldnamen binden, sondern generell an ein Array von Textwerten. Die gewünschte Ausgabe in obigem Beispiel wäre,

{ 
    "mName": "Carl Sanchez", 
    "mEmailID": "[email protected]", 
    "mPhoneNo": 7954041324, 

    "tutorTypes": [ 
     " Freelancer/Professional Tutor", 
     " Coaching Institute Teacher ", 
     " Corporate Professional " 
    ], 
    "disciplines": [ 
     " Japanese", 
     " German ", 
     " Hindi ", 
     " French " 
    ] 
} 

Die Eingangsquelle von JSON ist eine Datei, und ich mag die Ausgabe in einer Datei schreiben. Ich habe ein Programm versucht, diese mit Jackson Datenbindungs ​​API zu erreichen:

public static void removeDuplicateStringElementsFromAllArrays(String file) throws IOException { 

     Writer fileWriter = new BufferedWriter(new FileWriter(new File("out.json"))); 

     JsonFactory f = new MappingJsonFactory(); 
     JsonParser jp = f.createJsonParser(new File(file)); 

     parse(jp, fileWriter); 
    } 

    private static void parse(JsonParser jp, Writer writer) throws IOException{ 
     JsonToken current; 
     current = jp.nextToken(); 

     if(current != null){ 
      System.out.println(current.asString()); 
      writer.write(current.asString()); 
     } 

     if(current == JsonToken.START_ARRAY){ 
      if(jp.nextTextValue() != null){ 
       JsonNode node = jp.readValueAsTree(); 
       // Trim the String values 
       String[] values = ArraysUtil.trimArray("\"" , node.toString().split(","), "\""); 
       // Ensure that there is no duplicate value 
       values = new HashSet<String>(Arrays.asList(values)).toArray(new String[0]); 
       // Finally, concatenate the values back and stash them to file 
       String concatValue = String.join(",", values); 

       // Write the concatenated values to file 
       writer.write(concatValue); 
      } 
      else{ 
       parse(jp, writer); 
      } 
     } 
     else{ 
      // Move on directly 
      parse(jp, writer); 
     } 
    } 

ich mehrere Nullen als Ausgabe immer bin. Ich habe eine Idee, warum das passieren könnte. Ich denke, wenn ich jp.nextTextValue() rufe, ist der Parser weitergegangen und das Konstruieren eines Wertbaums könnte dazu geführt haben, aber ich bin nicht in der Lage, eine Problemumgehung dafür herauszufinden. Weiß jemand, wie ich die Aufgabe erfüllen könnte.

EDIT:

Ich will nur hier eine Sache hinzufügen - ich den Jackson-Databind API verwenden, weil es auf Streaming API gebaut wird, die effizient ist, wenn eine große JSON Quelle Parsen, die mein Fall ist. Daher würde eine Lösung, die dies berücksichtigt, geschätzt werden.

Antwort

0

Hier ist ein Beispiel mit Json Simple. Beachten Sie, dass dabei davon ausgegangen wird, dass die Arrays auf der Stammebene vorhanden sind, und dass in jedem Parameter nicht nach verschachtelten Arrays gesucht wird. Sie können eine Rekursion Logik hinzufügen, wenn Sie, dass

package test.json.jsonsimple; 

import java.io.FileNotFoundException; 
import java.io.FileReader; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.util.HashSet; 
import java.util.Iterator; 
import java.util.Map; 
import java.util.Set; 

import org.json.simple.JSONArray; 
import org.json.simple.JSONObject; 
import org.json.simple.parser.JSONParser; 
import org.json.simple.parser.ParseException; 

public class App 
{ 
    @SuppressWarnings("unchecked") 
    public static void main(String[] args) 
    { 
     System.out.println("Hello World!"); 

     JSONParser parser = new JSONParser(); 

     try { 
      JSONObject outmap = new JSONObject(); 
      Object obj = parser.parse(new FileReader("d:\\in.json")); 
      JSONObject jsonObject = (JSONObject) obj; 
      for(Object o : jsonObject.entrySet()){ 
       if(o instanceof Map.Entry){ 
        Map.Entry<String, Object> entry = (Map.Entry<String, Object>) o; 
        if(entry !=null){ 
         if(entry.getValue() instanceof JSONArray){ 
          Set<String> uniqueValues = removeDuplicates(entry.getValue()); 
          outmap.put(entry.getKey(), uniqueValues); 
         }else{ 
          outmap.put(entry.getKey(), entry.getValue()); 
         } 
        } 
       } 
      } 

      FileWriter file = new FileWriter("d:\\out.json"); 
      file.write(outmap.toJSONString()); 
      file.flush(); 
      file.close(); 

     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (ParseException e) { 
      e.printStackTrace(); 
     } 

    } 

    @SuppressWarnings("unchecked") 
    private static Set<String> removeDuplicates(Object value) { 
     Set<String> outset = new HashSet<String>(); 
     JSONArray inset = (JSONArray) value; 

     if (inset != null) { 
      Iterator<String> iterator = inset.iterator(); 
      while (iterator.hasNext()) { 
       outset.add(iterator.next()); 
      } 
     } 
     return outset; 
    } 
} 
3

erstellen Bohne Contact.java und erklären Eigenschaften als Set, für die Sie Duplikate entfernen möchten unterstützen wollen.

Wenn Sie das JSON serialisieren, erledigt das Set die Aufgabe, die Duplikate zu entfernen. Kein zusätzlicher Code ist erforderlich.

package com.tmp; 

import java.util.Set; 

public class Contact { 

    String  mName; 
    String  mEmailID; 
    long  mPhoneNo; 

    Set<String> tutorTypes; // to remove duplicates 
    Set<String> disciplines; // to remove duplicates 

    // setter and getter methods goes here...  
} 

Duplikate entfernen

package com.tmp; 

import java.io.File; 
import java.io.IOException; 

import com.fasterxml.jackson.databind.ObjectMapper; 


/** 
* 
* @author Ravi P 
*/ 
class Tmp { 

    public static void main(String[] args) throws IOException { 

     ObjectMapper mapper = new ObjectMapper(); 

     Contact contact = mapper.readValue(new File("D:\\tmp\\file.json"), Contact.class); 

     mapper.writeValue(new File("D:\\tmp\\file1.json"), contact); 

    } 
} 
Verwandte Themen