How to compare two lists/files?

Hello,

I am looking for forum assistance in developing File/String Compare function.

I am downloading data from mutual fund source using a list of tickers.
Every now and then, CSV list of funds changes. They may remove or add new fund.
StringCompare() function will be ideal but, I could not find this functionality in AB documentation.

The function needs to compare two lists of tickers (current against previous - last week's CSV)
and identify ticker list difference.

With the help of @PanoS (another very generous forum member) we tried the following idea;

// this code use StrMatch() and it is not good for comparing two lists

GuiButton( "Set_Static_List", 5, 10, 110, 95, 24, 1);
id = GuiGetEvent( 0, 0 ); 	event = GuiGetEvent( 0, 1 );  SetStaticVar=0;
if( id == 5 && event == 1 ) {SetStaticVar=1; GuiSetText("Button clicked",5); }

printf(" LIST1  = %s\n,LIST2 = %s\n", "zz,C,CAT,DD,GE,IBM,INTC,MSFT", "zz,C,CAT,DD,GE,MSFT,Richard" );
if(SetStaticVar)
{
LIST1 = StaticVarSetText( "LIST1", "zz,C,CAT,DD,GE,IBM,INTC,MSFT");
LIST2 =  StaticVarSetText( "LIST2","zz,C,CAT,DD,GE,MSFT,Richard");
}

LIST1 = StaticVargetText( "LIST1");
LIST2 = StaticVargetText( "LIST2");

// the idea behind this loop is to remove one by one the elements from the lists.
for( i = 0; ( sym = StrExtract( LIST1, i ) ) != ""; i++ )
{
    printf( "ItemList1 %g = %s\n", i, sym );

    for( j = 0; ( sym2 = StrExtract( LIST2, j ) ) != ""; j++ )
    {
        printf( "<b>ItemList2 \t %g = %s </b>\n", j, sym2 );

        if( StrMatch( sym, sym2 ) )
        {
            printf( "StrMatch \t\t" + sym  + "-" + sym2  + "\n" );
            //if string match, remove the item from the lists
            remove1ListItem = StrReplace( LIST1, sym, "" );
            StaticVarSetText( "LIST1", remove1ListItem );

            remove2ListItem = StrReplace( LIST2, sym2, "" );
            StaticVarSetText( "LIST2", remove2ListItem );
            break;
        }
        //else
        printf( "else Not-Match \t" + sym  + " - " + sym2  + "\n" );
    }
}

In the above example we compare two LISTS which are made up from sample ticker lists (LIST1 and LIST2) rather than reading ticker list strings from the CSV files, but the logic is the same.

The AFL code does not produce desired result. In the interpretation window the letter C from INTC is missing (after the loop is finished). We think that this happens because we use StrMatch().

Which function can we use instead ?. Is there a better way to solve this problem - how to compare two lists - since we don't have a native StrCompare() function?

Any help or suggestion will be greatly appreciated.

Kind Regards
Richard

since we don't have a native StrCompare() function?

Not true. We do have native string comparison. There are == and != operators that compare strings too (not only numbers).

string1 = "AB,CD,EF";
string2 = "AB,CD,EF";
string3 = "AC,CD,X";

if( string1 == string2 )
{
  printf("string1 and 2 are the same\n");
}

if( string1 != string3 )
{
   printf("string1 and 3 are NOT the same\n");
}

StrMatch is wildcard matching, not comparision. See the manual: AFL Function Reference - STRMATCH

Also, instead of doing StrReplace several times, you should operate on symbols that you extracted just ADDING those that don't match to "list of differences" or add those that match to "list of matching symbols". Then you can use that list to StrReplace ONCE.

// inside the loop that you wrote
if( sym == sym2 )
{ 
   list_of_matches += sym + ","; // build comma-separate list of matching symbols 
}
else
{
  // different symbols
  list_of_differences += sym + "-" + sym2 + ","; 
}

Instead of string extraction you can also just compare both strings by character, to easily find first differing character. Everything before that is the same. Differences are everything that comes after first differing character.

string3 = "AB,CD,EC";

len = StrLen(string1);

last_comma = -1;

for( i = 0; i < len; i++ )
{
	ch = Asc( string1, i ); // get ASCII code at i-th position
	
	if( ch == ',' ) last_comma = i;
	if( ch != Asc( string3, i ) )
	{
	   printf( "First differing position is %g, last_comma at %g", i, last_comma );
	   break;
	}
}

if( i == len ) printf( "string1 is fully contained in string3");
4 Likes

Thank you very much - Tomasz.

Sometimes "we cannot see the wood for the trees" :slightly_smiling_face: or in Polish "czasami drzewa zaslaniaja las". I didn't mean to be negative or critical. We just could not see the obvious.

Amibroker software and support you provide is excellent - "perfectionist!"
I use many business software applications in my professional life and none of the comes even close.
I don't post questions very often because in most cases I find the answer I am looking for on the forum, in AB KB or Help documentation.

All solutions you provided should work. Although, I need to study it a bit more.
String comparison by character is a brilliant suggestion/solution.

Thanks again for your prompt reply.

Kind Regards
Richard

2 Likes

Thank you @Tomasz very much for your detailed reply.

What we need here is two outputs.

  1. First output is to find the elements form List1 that are NOT exist in List2,
  2. Second output is to find the elements form List2 that are NOT exist in List1,

I read how other programming language they deal with this problem, and I saw an answer that they try to remove the matching elements form the Lists, To find out the UNcommon items.

So please, how can we have those two outputs?

Thank you

You already have solution and code in previous reply.

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.