11import json
22from collections import OrderedDict
3- from typing import Dict , List , Tuple
3+ from typing import Any , Dict , List , Tuple
44
55JsonPrimitive = str | int | float | bool | None
66type JsonValue = JsonPrimitive | JsonObject | JsonArray
@@ -97,6 +97,44 @@ def traverse_array(self, items: JsonArray, path: list[str]) -> None:
9797 self .process_collection (item , base_path , f"{ array_path } [{ idx } ]" )
9898
9999
100+ def check_for_duplicate_keys (pairs : list [tuple [str , Any ]]):
101+ keys = {}
102+ dupes = {}
103+ for key , value in pairs :
104+ print (f"Processing key: { key } , value: { value } " )
105+ if key in keys :
106+ if key not in dupes :
107+ dupes [key ] = []
108+ dupes [key ].append (value )
109+ continue
110+
111+ keys [key ] = value
112+
113+ if dupes :
114+ keys ["__duplicates__" ] = dupes
115+
116+ return keys
117+
118+
119+ def flatten_duplicates (data : dict | list ) -> list [str ]:
120+ duplicates = []
121+
122+ for key , value in data .items () if isinstance (data , dict ) else enumerate (data ):
123+ if key == "__duplicates__" :
124+ duplicates .extend ([f"{ dupe_key } " for dupe_key in value .keys ()])
125+ continue
126+
127+ if isinstance (value , (dict , list )):
128+ dupes = flatten_duplicates (value )
129+
130+ path = f"{ key } " if isinstance (data , dict ) else f"[{ key } ]"
131+ duplicates .extend ([f"{ path_key } .{ dupe } " for dupe in dupes ])
132+
133+ print (f"flatten_duplicates data={ data } dupes={ duplicates } " )
134+
135+ return duplicates
136+
137+
100138def check_duplicate_keys (json_content : str ) -> Tuple [List [str ], List [str ]]:
101139 """Find all duplicate keys in a JSON string.
102140
@@ -107,6 +145,20 @@ def check_duplicate_keys(json_content: str) -> Tuple[List[str], List[str]]:
107145 A key is considered duplicate if it appears multiple times within
108146 the same object, regardless of nesting level or array position.
109147 """
148+
149+ use_hooks_approach = True
150+
151+ if use_hooks_approach :
152+ try :
153+ dupe_data = json .loads (
154+ json_content , object_pairs_hook = check_for_duplicate_keys
155+ )
156+ duplicate_paths = [f"root.{ path } " for path in flatten_duplicates (dupe_data )]
157+ duplicate_keys = [key .split ("." )[- 1 ] for key in duplicate_paths ]
158+ return duplicate_keys , duplicate_paths
159+ except json .JSONDecodeError :
160+ raise ValueError ("Error: Invalid JSON format" )
161+
110162 try :
111163 parsed_data = json .loads (json_content , object_pairs_hook = lambda pairs : pairs )
112164 print ("Parsed JSON:" , parsed_data )
0 commit comments