Matt Klein Posted November 4, 2005 Posted November 4, 2005 I am trying to write a custom function to remove all iterations of a value from a list of values. For instance, say I have a value list in a field called "IDs": 1 2 3 4 2 Now say I want to remove all the twos from this value list. I could use substitute and all that, but I don't want to. No real reason other than I like the new Values functions that FileMaker has for us. So I wrote two custom functions: DeleteValue(value; valueList; startingValueNumber) Let([ $$value = value; valueCurrent = GetValue(valueList; startingValueNumber); $$totalValues = ValueCount(valueList)]; Case(startingValueNumber <= $$totalValues; Case(value = valueCurrent; DeleteValueSub ( valueList ; startingvalueNumber ); DeleteValue(value; valueList; startingValueNumber + 1))//End Case )//End Case )//End Let and DeleteValueSub(valueList; valueNumber): Let([ valueListNew = LeftValues ( valueList; valueNumber - 1) & RightValues ( valueList; $$totalValues - valueNumber)]; DeleteValue ( $$value ; valueListNew ; 1) )//End Let In the example above I would do a Set Field[iDs] with a calculation that is : DeleteValue(2;IDs;1) Instead of just getting rid of the twos it gets rid of everything. I can get DeleteValue() to work if I only want the first iteration of a value to be deleted if I change DeleteValueSub() to: DeleteValueSub(valueList; valueNumber): Let([ valueListNew = LeftValues ( valueList; valueNumber - 1) & RightValues ( valueList; $$totalValues - valueNumber)]; valueListNew )//End Let I have walked through the recursion in my head and can't figure out why is removing all values. Anyone offer some help?
Ender Posted November 5, 2005 Posted November 5, 2005 How about this one: OmitValue ( valueList ; valueToOmit ) = //OmitValue ( valueList ; valueToOmit ) = Case(LeftValues ( valueList ; 1 ) <> valueToOmit & ¶; LeftValues ( valueList ; 1 )) & Case(ValueCount ( valueList ) > 1; OmitValue(RightValues(valueList; ValueCount(valueList) - 1); valueToOmit)) Though a simple substitute is easier.
comment Posted November 5, 2005 Posted November 5, 2005 I have only glanced at this (after all, it has no practical purpose), and it seems to me that while you are deleting some values, you are NOT returning the kept ones. Your first Case() should include an alternative result of valueList, when startingValueNumber exceeds the total value count. Because that's what you'll have at the end of your run, after your list is cleaned. As Ender shows, this can done without a subfunction, and without bothering the user with the startValue parameter. Note also that you are examining the same values over and over (starting always with the first value), until the list is completely cleaned. This is not very efficient.
Matt Klein Posted November 7, 2005 Author Posted November 7, 2005 Thanks Ender!! I like the lack of need for a sub function and it does what I need. I appreciate your time! The problem with a Substitute is that you have to remember to use the ¶ characters before and after the value since substitute works with the value as a string of characters instead of a value as the new Value functions do. Because of the need for before and after ¶ characters, you then run into problems with the first(no ¶ before) and last(no ¶ after) values, unless you make sure the first character in the field is ¶ and the last character is ¶. I wanted this custom function so that my developers and I could simply state the value and the value list without dealing with the substitute function as is described above. (after all, it has no practical purpose) comment, as for the practicality of this function, it would appear that it is a subjective issue unless you have a better way, other than using the substitute function, to remove values from a list. Your first Case() should include an alternative result of valueList, when startingValueNumber exceeds the total value count. You were absolutely right. As soon as I added that alternative result, my custom function worked perfectly. Note also that you are examining the same values over and over (starting always with the first value), until the list is completely cleaned. This is not very efficient. My concern is/was not the efficiency of the computing the function had to do as much as it is/was the efficiency it would afford myself and my developers. It is much more simple to merely state the value and the value list than it is to write the substitute calc to handle this which is one of the great things about custom functions. Also, I am new to recursion and custom functions so I imagine that alot of the functions I write are not the most efficient, but they work.
comment Posted November 7, 2005 Posted November 7, 2005 In your original post you said: I could use substitute and all that, but I don't want to. No real reason other than I like the new Values functions In my mind, "no real reason" translated as having no practical purpose. I was merely explaining why I haven't spent more time analyzing your function. Can't see what the fuss is about. Substitute() works without iterations, therefore will be faster. There is no need to "make sure the first character in the field is ¶ and the last character is ¶". You can add these in the calculation itself: Substitute ( ¶ & list & ¶ ; ¶ & item & ¶ ; ¶ ) This can (though usually doesn't need to) be further processed to remove unnecessary CR's.
Recommended Posts
This topic is 6954 days old. Please don't post here. Open a new topic instead.
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now