Filtering only specific items from Array

Anything beyond the basics in using the LiveCode language. Share your handlers, functions and magic here.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
dcpbarrington
Posts: 87
Joined: Tue Nov 13, 2007 6:40 pm

Filtering only specific items from Array

Post by dcpbarrington » Wed Dec 19, 2012 6:29 pm

Here is my challenge. I have created an array based on content that is in an XML tree. I now want to filter the array to create a new array with only specific elements from the array.

Array
date[1] 2012-12-12
value[1] 10.4
new[1] 0 NOTE: either 0 or 1 to indicate if node is new entry into array
....
date[2] 2012-12-12
value[2] 12.3
new[2] 1
....
date[3] 2012-12-12
value[3] 11
new[3] 1
....

I want to create a function that will create a new array with only the elements that have the new flag set to 1.
The challenge is that I want to create a generic function that does not specifically know what the labels are for all the keys in the array.
If a new element label is added to the array I want the function to determine the list of keys from the array.
Here is my code so far, but I'm doing something wrong because I'm not getting a unique list of keys or I'm not using the key list properly.

Code: Select all

   -- convert the information from the XML string into an ARRAY
   split theDataArray by "|" and tab
   
   -- Look through each of the nodes to see if the NEW flag is set
   put 1 into tNewItem
   put 1 into tItem
   put the keys of theDataArray into tKeys
   repeat while tItem < tNodeCount
      if theDataArray["new["& tItem &"]"] = "1" then
         repeat with i=1 to the number of items of tKeys
            put item i of tKeys into tItemName
            put theDataArray[ tItemName&"["& tItem &"]"]  into theNewArray[tItemName&"["& tNewItem &"]"] 
         end repeat
         add 1 to tNewItem
      end if
      add 1 to tItem
   end repeat

Thanks for the help on this challenge.

Simon
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3901
Joined: Sat Mar 24, 2007 2:54 am

Re: Filtering only specific items from Array

Post by Simon » Wed Dec 19, 2012 10:51 pm

Actually if you remove the array idea:

Code: Select all

replace "|" with cr in theDataArray
replace tab with "" in theDataArray
set itemDel to space
repeat for each line tLine in theDataArray
   ## tLine is the ACTUAL content of that line!

   if item 3 of tLine = 1 then 
    
      ## you cannot modify tLine, so we simply create a new variable!
      put tLine & CR after tNewList
   end if
end repeat

## delete trailing CR
delete char -1 of tNewList
...
that would give you your new items. (Thank you Klaus)
Apparently repeat for each is incredibly fast.

Simon
I used to be a newbie but then I learned how to spell teh correctly and now I'm a noob!

dcpbarrington
Posts: 87
Joined: Tue Nov 13, 2007 6:40 pm

Re: Filtering only specific items from Array

Post by dcpbarrington » Wed Dec 19, 2012 11:42 pm

Thanks for the quick response, but this is only true if the NEW data item is always in the third column for the data.

The challenge is that NEW is just a tag is an XML tree. When I retrieve the XML node, I don't have control over where the NEW tag is in the data returned.

I should have included the XML code to give you a better understanding of what I'm trying to do. The XML node can have from 5 to 10 data elements and NEW is always in the list.

Code: Select all

   put revXMLChildContents(pTreeID, tNode, tab, "|", true, -1) into theDataArray
   handleRevXMLerror theDataArray
   if the result is not empty then 
      put "ERROR: GET:NEW:Node="&pNodeType & " Error Code= "& the result into tErrorCondition
      return tErrorCondition
   end if
   
   -- convert the information from the XML string into an ARRAY
   split theDataArray by "|" and tab
   
   -- Look through each of the nodes to see if the NEW flag is set
   put 1 into tNewItem
   put 1 into tItem
   put the keys of theDataArray[1] into tKeys
   repeat while tItem < tNodeCount
      if theDataArray["new["& tItem &"]"] = "1" then
         repeat with i=1 to the number of items of tKeys
            put item i of tKeys into tItemName
            put theDataArray[ tItemName&"["& tItem &"]"]  into theNewArray[tItemName&"["& tNewItem &"]"] 
         end repeat
         add 1 to tNewItem
      end if
      add 1 to tItem
   end repeat


Simon
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3901
Joined: Sat Mar 24, 2007 2:54 am

Re: Filtering only specific items from Array

Post by Simon » Thu Dec 20, 2012 1:56 am

Ahh, sorry I was just looking at your array example.


Simon
I used to be a newbie but then I learned how to spell teh correctly and now I'm a noob!

dcpbarrington
Posts: 87
Joined: Tue Nov 13, 2007 6:40 pm

Re: Filtering only specific items from Array

Post by dcpbarrington » Thu Dec 20, 2012 6:47 pm

I figured out what I need to do. Don't know if it is the most efficient, but it work.
The key was to extract a list of tags from the data array and then extract only the items that matched the NEW tag.

Code: Select all


   put revXMLChildContents(pTreeID, tNode, tab, "|", true, -1) into theDataArray
   handleRevXMLerror theDataArray
   if the result is not empty then 
      put "ERROR: GET:ALL:Node="&pNodeType & " Error Code= "& the result into tErrorCondition
      return tErrorCondition
   end if
   
   -- convert the information from the XML string into an ARRAY
   split theDataArray by "|" and tab
   
   -- create a list of key tags
   put the keys of theDataArray into tKeys
   repeat for each line tKeyTag in tKeys
      if tKeyTag contains "[1]" then
         replace "[1]" with "" in tKeyTag
         put tKeyTag & return after tKeyList
      end if
   end repeat   
   delete the last line of tKeyList
   
   -- Look through each of the nodes to see if the NEW flag is set
   put 1 into tNewItem
   put 1 into tItem
   repeat while tItem <= tNodeCount
      if theDataArray["new["& tItem &"]"] = "1" then
         repeat for each line tItemName in tKeyList
            put theDataArray[ tItemName&"["& tItem &"]"]  into theNewArray[tItemName&"["& tNewItem &"]"] 
         end repeat
         add 1 to tNewItem
      end if
      add 1 to tItem
   end repeat
Is there a better way to get the list of tag names in an XML node?

Post Reply