Solved

To remove duplicate values and return unique array

Posted on 2011-03-03
10
2,032 Views
Last Modified: 2013-12-26
I am in search of a powerbuilder fuction which would accept an arry, remove duplicate values from array and return unique values of array

for example
is_dwm_data_colname[1] = 'sman_code'
is_dwm_data_colname[2] = 'area_code'
is_dwm_data_colname[3] = 'mfg_code'
is_dwm_data_colname[4] = 'area_code'
is_dwm_data_colname[5] = 'mfg_code'
is_dwm_data_colname[6] = 'sman_code'

the returned array should be
is_dwm_data_colname[1] = 'sman_code'
is_dwm_data_colname[2] = 'area_code'
is_dwm_data_colname[3] = 'mfg_code'


0
Comment
Question by:Mehram
  • 5
  • 3
  • 2
10 Comments
 
LVL 2

Accepted Solution

by:
lbushby earned 300 total points
Comment Utility
There's no built in function but you could achieve what you want by copying the array to a column in a datastore then sort+filtering it to hide duplicate values before copying the column back to the array.  Example below:

// copy the array to a datastore (assumes datastore has been assigned a dataobject
// that contains a string column called 'dwm_data_colname')
lds_dedupe.Object.dwm_data_colname.primary = is_dwm_data_colname[]

// apply a sort+filter that discards duplicates
lds_dedupe.SetSort('dwm_data_colname A')
lds_dedupe.Sort()
lds_dedupe.Setfilter('GetRow()=1 OR dwm_data_colname <> dwm_data_colname[-1]')
lds_dedupe.Filter()

// copy the deduped column from the datastore back to the array
is_dwm_data_colname[] = lds_dedupe.Object.dwm_data_colname.primary

// the array now only contains distinct values
0
 

Author Comment

by:Mehram
Comment Utility
Hi lbushby

I understand.

GetRow()=1 OR dwm_data_colname <> dwm_data_colname[-1] is a magical expression. My object Is achieved, but, please allow me to ask
Is it possible to create an imaginary datastore?
If so what is the syntax/script?

Thanks for your help.
0
 

Author Comment

by:Mehram
Comment Utility
My the term "imaginary" I mean dataobject->datastore to be created and destroyed at runtime
0
 
LVL 2

Assisted Solution

by:lbushby
lbushby earned 300 total points
Comment Utility
Datastores objects are created and destroyed using CREATE/DESTROY.  Creating a dataobject at runtime can be done in several different ways.  Assuming you are actually connected to a database then probably the easiest way is to use SyntaxFromSQL to create a dataobject based on a SELECT statement.  The exact syntax will depend on the database in question.  The example below will work with Sybase SQLAnywhere which provides a 'dummy' table:

// EXAMPLE

datastore      lds_datastore
string      ls_syntax
string      ls_errors

// create a datastore
lds_datastore = create datastore

// generate syntax for a single string column called dwm_data_colname
// assumes SQLCA is connected to a database
ls_syntax = SQLCA.SyntaxFromSQL("SELECT '' AS dwm_data_colname FROM dummy", "", ls_errors )

// use the syntax to create a new dataobject
lds_datastore.Create(ls_syntax,ls_errors)

// the datastore is now ready to use as per the previous example

// having finished with the datastore, destroy it
destroy lds_datastore
 
0
 
LVL 1

Assisted Solution

by:goodwinfam
goodwinfam earned 200 total points
Comment Utility
Here is what I have used for awhile extracted from my util nvo...   Note that this is from an export, so copy and paste accordingly (the first line before the ";" is the function and arg definition - not part of the script..

-------------------

public function integer of_arrayunique (long al_sourcevalues[], ref long al_uniquevalues[]);int            li_pos,li_cnt,li_tcnt,li_cnt2
long            ll_empty[],ll_value,ll_sourcevalues[]
boolean      lb_skip


// Initialize Return Array
ll_sourcevalues = al_sourcevalues
al_uniquevalues = ll_empty

// Loop Through Array Values
li_tcnt = upperbound(ll_sourcevalues)
for li_cnt = 1 to li_tcnt

      // Remove NULL Values
      lb_skip = FALSE
      ll_value = ll_sourcevalues[li_cnt]
      if isnull(ll_value) then continue

      // Compare
      for li_cnt2 = 1 to li_pos
            if ll_value = al_uniquevalues[li_cnt2] then
                  lb_skip = TRUE
                  continue
            end if
      next
      if lb_skip then continue

      // Include
      li_pos ++
      al_uniquevalues[li_pos] = ll_value

next

// Return
return(upperbound(al_uniquevalues))
end function

----------------------------------------------------------------

public function integer of_arrayunique (string as_sourcevalues[], ref string as_uniquevalues[], boolean ab_ignorecase);int            li_pos,li_cnt,li_tcnt,li_cnt2
string      ls_empty[],ls_value
boolean      lb_skip


// Initialize Return Array
as_uniquevalues = ls_empty

// Loop Through Array Values
li_tcnt = upperbound(as_sourcevalues)
for li_cnt = 1 to li_tcnt

      // Get Value
      lb_skip = FALSE
      ls_value = as_sourcevalues[li_cnt]
      if ab_ignorecase then
            ls_value = trim(lower(ls_value))
            if ls_value = "" then continue
      end if

      // Determine if Unique
      for li_cnt2 = 1 to li_pos
            if ls_value = lower(as_uniquevalues[li_cnt2]) then
                  lb_skip = TRUE
                  exit
            end if
      next
      if lb_skip then continue

      // Include
      li_pos ++
      as_uniquevalues[li_pos] = ls_value

next

// Return
return(upperbound(as_uniquevalues))
end function

Here are the other the functions that call the fully qualified function...

public function integer of_arrayunique (ref long al_return[])            ;return(of_arrayunique(al_return,al_return))
public function integer of_arrayunique (ref string as_return[])      ;return(of_arrayunique(as_return,as_return,FALSE))
public function integer of_arrayunique (ref string as_return[], boolean ab_ignorecase);return(of_arrayunique(as_return,as_return,ab_ignorecase))
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:Mehram
Comment Utility
Great

The benefit of asking at EE is that you learn a lot of new things.
The of_arrayunique function has gone  easily into our user object uo_functions.

lbushby:
The creation of datastore at runtime was thrilling. I was in search of this since a long time.

U experts are lovely and Unselfish.

My best regards to both of U

(Mat)
0
 

Author Closing Comment

by:Mehram
Comment Utility
Thanks a lot
0
 
LVL 1

Expert Comment

by:goodwinfam
Comment Utility
Thanks,  
To appear less A.D.D. I  adjusted a few things...Please note that you may not wish to always skip NULL or empty values which is the assumption in these scripts.  The option whether or not to do so might also be a flag you pass (which I have in my actual code).  In the function handling strings you should add a line looking for a null value following "ls_value = as_sourcevalues[li_cnt]" like  (if isinull(ls_value) then ls_value = "" or if you are skipping empty values "if isinull(ls_value) then continue"...).  
0
 
LVL 1

Expert Comment

by:goodwinfam
Comment Utility
Change "continue" to "exit" in the compare section for comparing long values above.

The final string value compare script...  
----------------
public function integer of_arrayunique (string as_sourcevalues[], ref string as_uniquevalues[], boolean ab_ignorecase, boolean ab_includeempty, boolean ab_untrimmed);int            li_cnt,li_tcnt,li_uniquecnt,li_totuniquecnt
string      ls_empty[],ls_value
boolean      lb_skip


// Initialize Return Array
as_uniquevalues = ls_empty

// Loop Through Array Values
li_tcnt = upperbound(as_sourcevalues)
for li_cnt = 1 to li_tcnt

      // Get Value
      lb_skip = FALSE
      ls_value = as_sourcevalues[li_cnt]
      if NOT(ab_untrimmed) then ls_value = trim(ls_value)
      if NOT(ab_includeempty) AND ( isnull(ls_value) or ls_value = "" ) then continue

      // Compare (this loop skipped first time through because li_totuniquecnt will = 0)
      for li_uniquecnt = 1 to li_totuniquecnt
            choose case TRUE
                  case ls_value = as_uniquevalues[li_uniquecnt]                                                                                                                                    ; lb_skip = TRUE      ; exit
                  case ab_ignorecase AND (lower(ls_value) = lower(as_uniquevalues[li_uniquecnt]))                                                                  ; lb_skip = TRUE      ; exit
                  case (ab_ignorecase AND ab_untrimmed) AND (lower(trim(ls_value)) = lower(trim(as_uniquevalues[li_uniquecnt])))      ; lb_skip = TRUE      ; exit
            end choose
      next
      if lb_skip then continue

      // Include
      li_totuniquecnt ++
      as_uniquevalues[li_totuniquecnt] = ls_value

next

// Return
return(upperbound(as_uniquevalues))
end function
0
 

Author Comment

by:Mehram
Comment Utility
Thanks again goodwinfam
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Update (December 2011): Since this article was published, the things have changed for good for Android native developers. The Sequoyah Project (http://www.eclipse.org/sequoyah/) automates most of the tasks discussed in this article. You can even fin…
How to install Selenium IDE and loops for quick automated testing. Get Selenium IDE from http://seleniumhq.org (http://seleniumhq.org) Go to that link and select download selenium in the right hand columnThat will then direct you to their downlo…
The viewer will learn how to use and create keystrokes in Netbeans IDE 8.0 for Windows.
The viewer will learn how to use and create new code templates in NetBeans IDE 8.0 for Windows.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now