2017-03-14 18 views
2

重複した値を含む複数のテキスト配列を持つJSONファイルがあります。例:ジャンクションを使用してすべてのJSON配列から重複するテキスト値を削除します。

{ 
    "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 " 
    ] 
} 

JSONソース内のすべての配列から重複した値(テキスト値)を削除します。上記の例では、配列から重複した言語とチューターの型を削除することになります。該当する出力は、上記のJSONソースで、適用可能な場合は重複値だけが削除されます。また、コードを特定のJSONフィールド名にバインドするのではなく、一般に任意の配列のテキスト値にバインドする必要があります。上記の例の出力は、

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

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

です。入力ソースはファイルなので、出力をファイルに書きたいと思います。 私はジャクソンデータ・バインディングAPIを使用してこれを実現するためのプログラムを試みた:

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); 
     } 
    } 

私は出力として、いくつかのNULLを取得しています。私はなぜこれが起こっているのかという考えを持っています。私はjp.nextTextValue()と呼んだとき、パーサーが動いて、値ツリーを構築している可能性がありますが、これに対する回避策を見つけることができません。誰もが知っている、私はどのようにタスクを達成するために行くかもしれない。

EDIT:

ただ、ここで一つのことを追加したい - それは私の場合である大JSONソースを、解析時に効率的でストリーミングAPI上に構築されているので、私はジャクソンのDataBind APIを使用しています。したがって、これを考慮に入れた解決策が認められるでしょう。

答えて

0

ここでは、Json Simpleを使用した例を示します。これは配列がルートレベルに存在することを前提としており、各パラメータのネストされた配列をチェックしません。あなたがその

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

がBean Contact.javaを作成し、重複を削除する対象のSetとしての性質を宣言するサポートしたい場合は、再帰ロジックを追加することができます。

JSONをシリアル化すると、セットは重複を削除するジョブを行います。特別なコードは必要ありません。

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...  
} 

重複

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); 

    } 
} 
を削除します
関連する問題