@@ -439,10 +439,6 @@ private boolean doValueHighlight(Map<String,Object> options, String value) {
439439 }
440440 }
441441
442- private void highlightAndPrint (int width , String style , String object , boolean doValueHighlight ) {
443- highlightAndPrint (width , valueHighlighter (style ), object , doValueHighlight );
444- }
445-
446442 private void highlightAndPrint (int width , SyntaxHighlighter highlighter , String object , boolean doValueHighlight ) {
447443 for (String s : object .split ("\\ r?\\ n" )) {
448444 AttributedStringBuilder asb = new AttributedStringBuilder ();
@@ -671,17 +667,17 @@ private List<Object> objectToList(Object obj) {
671667 return out ;
672668 }
673669
674- private boolean similarSets (Set <String > ref , Set <String > c2 , double threshold ) {
675- boolean out = c2 .containsAll (ref );
676- if (!out ) {
677- int matches = 0 ;
678- for (String s : ref ) {
679- if (c2 .contains (s )) {
680- matches += 1 ;
670+ private boolean similarSets (final Set <String > ref , final Set <String > c2 , final int matchLimit ) {
671+ boolean out = false ;
672+ int limit = matchLimit ;
673+ for (String s : ref ) {
674+ if (c2 .contains (s )) {
675+ limit --;
676+ if (limit == 0 ) {
677+ out = true ;
678+ break ;
681679 }
682680 }
683- double r = (1.0 *matches )/ref .size ();
684- out = r > threshold ;
685681 }
686682 return out ;
687683 }
@@ -766,8 +762,14 @@ private void highlightAndPrint(Map<String, Object> options, Object obj) {
766762 Object elem = collection .iterator ().next ();
767763 boolean convert = canConvert (elem );
768764 if ((elem instanceof Map || convert ) && !options .containsKey (Printer .TO_STRING )) {
769- Map <String , Object > map = convert ? objectToMap (options , elem )
770- : keysToString ((Map <Object , Object >) elem );
765+ List <Map <String ,Object >> convertedCollection = new ArrayList <>();
766+ Set <String > keys = new HashSet <>();
767+ for (Object o : collection ) {
768+ Map <String , Object > m = convert ? objectToMap (options , o )
769+ : keysToString ((Map <Object , Object >) o );
770+ convertedCollection .add (m );
771+ keys .addAll (m .keySet ());
772+ }
771773 List <String > _header ;
772774 List <String > columnsIn = optionList (Printer .COLUMNS_IN , options );
773775 List <String > columnsOut = !options .containsKey ("all" ) ? optionList (Printer .COLUMNS_OUT , options )
@@ -776,30 +778,38 @@ private void highlightAndPrint(Map<String, Object> options, Object obj) {
776778 _header = (List <String >) options .get (Printer .COLUMNS );
777779 } else {
778780 _header = columnsIn ;
779- _header .addAll (map . keySet () .stream ()
781+ _header .addAll (keys .stream ()
780782 .filter (k -> !columnsIn .contains (k ) && !hasMatch (columnsOut , k ))
781783 .collect (Collectors .toList ()));
782784 }
783785 List <String > header = new ArrayList <>();
784786 List <Integer > columns = new ArrayList <>();
785787 int headerWidth = 0 ;
786788 Set <String > refKeys = new HashSet <>();
787- for (String value : _header ) {
788- if (!map .containsKey (value .split ("\\ ." )[0 ]) && !map .containsKey (value )) {
789+ for (String v : _header ) {
790+ String value = v .split ("\\ ." )[0 ];
791+ if (!keys .contains (value )) {
789792 continue ;
790793 }
791- if (options .containsKey (Printer .COLUMNS )) {
792- // do nothing
793- } else if (!options .containsKey (Printer .STRUCT_ON_TABLE )) {
794- Object val = mapValue (options , value , map );
795- if (!simpleObject (val )) {
794+ if (!options .containsKey (Printer .COLUMNS ) &&
795+ !options .containsKey (Printer .STRUCT_ON_TABLE )) {
796+ boolean simple = true ;
797+ for (Map <String ,Object > m : convertedCollection ) {
798+ if (m .containsKey (value )) {
799+ Object val = mapValue (options , v , m );
800+ if (!simpleObject (val )) {
801+ simple = false ;
802+ }
803+ break ;
804+ }
805+ }
806+ if (!simple ) {
796807 continue ;
797808 }
798809 }
799- String rk = map .containsKey (value ) ? value : value .split ("\\ ." )[0 ];
800- refKeys .add (rk );
801- header .add (value );
802- String cn = columnName (value , options .containsKey (Printer .SHORT_NAMES ));
810+ refKeys .add (value );
811+ header .add (v );
812+ String cn = columnName (v , options .containsKey (Printer .SHORT_NAMES ));
803813 columns .add (cn .length () + 1 );
804814 headerWidth += cn .length () + 1 ;
805815 if (headerWidth > width ) {
@@ -809,14 +819,11 @@ private void highlightAndPrint(Map<String, Object> options, Object obj) {
809819 if (header .size () == 0 ) {
810820 throw new Exception ("No columns for table!" );
811821 }
812- double mapSimilarity = 0.8 ;
813- if (options .containsKey (Printer .MAP_SIMILARITY )) {
814- mapSimilarity = ((BigDecimal )options .get (Printer .MAP_SIMILARITY )).doubleValue ();
815- }
816- for (Object o : collection ) {
817- Map <String , Object > m = convert ? objectToMap (options , o )
818- : keysToString ((Map <Object , Object >) o );
819- if (o instanceof Map && !similarSets (refKeys , m .keySet (), mapSimilarity )) {
822+ double mapSimilarity = ((BigDecimal )options .getOrDefault (Printer .MAP_SIMILARITY
823+ , new BigDecimal ("0.8" ))).doubleValue ();
824+ int matchLimit = (int )Math .ceil (header .size () * mapSimilarity );
825+ for (Map <String , Object > m : convertedCollection ) {
826+ if (!similarSets (refKeys , m .keySet (), matchLimit )) {
820827 throw new Exception ("Not homogenous list!" );
821828 }
822829 for (int i = 0 ; i < header .size (); i ++) {
@@ -847,7 +854,7 @@ private void highlightAndPrint(Map<String, Object> options, Object obj) {
847854 }
848855 asb .columnSubSequence (0 , width ).println (terminal ());
849856 int row = 0 ;
850- for (Object o : collection ) {
857+ for (Map < String , Object > m : convertedCollection ) {
851858 AttributedStringBuilder asb2 = new AttributedStringBuilder ().tabs (columns );
852859 if (doRowHighlight (row , tableRows )) {
853860 asb2 .style (prntStyle .resolve (".rs" ));
@@ -859,8 +866,6 @@ private void highlightAndPrint(Map<String, Object> options, Object obj) {
859866 asb2 .append ("\t " );
860867 }
861868 row ++;
862- Map <String , Object > m = convert ? objectToMap (options , o )
863- : keysToString ((Map <Object , Object >) o );
864869 for (int i = 0 ; i < header .size (); i ++) {
865870 if (i > 0 ) {
866871 asb2 .append (columnSep );
0 commit comments