Check for structure key in array element using cfscript - coldfusion

I am trying to loop over an array called meta.
I am having issues with checking if an element exists. In this array sometimes the length is present and sometimes it is not. I am trying to get something like this to work:
for (i=1;i LTE ArrayLen(meta);i=i+1) {
if (meta[i].length==undefined) {
maxLen = '1';
}
else
{
maxLen = meta[i].length;
}
}
I cannot seem to get the syntax right.

I think you want a structkeyexists.
if (structkeyexists(meta[i],"length") ....

Related

Correct way to write only the first element of a c++ stl vector

I have a c++ code that at one part it stored some values of a measurement in a vector and this vector is a part of set of data schema which is serialized and then sent to a streamer.
There is new requirement that for a specific case I need just one value of the measurement which is always rewritten with the latest one, but I don't want to change the vector variable in order to keep the same schema. So I thought that for that case to rewrite each time the first element of the vector, something like this
vector<int> store_measurements;
int measurement = 10;
if (condition == "several_values")
{
store_measurements.pushback(measurement);
}
else
{
store_measurements.at(0) = measurement ;
}
It seems to work fine when the vector is not cleared, but I'd like to ask if this is the correct way to do that or there is a more preferable way to do it?
You can use the front() function.
vector<int> store_measurements;
int measurement = 10;
if (condition == "several_values")
{
store_measurements.push_back(measurement);
}
else
{
store_measurements.resize(1);
store_measurements.front() = measurement ;
}
Edit:
Based on the comments I added store_measurements.resize(1); before the assignment
I would probably use assign() which replaces all the values in the vector like this:
if (condition == "several_values")
{
store_measurements.push_back(measurement);
}
else
{
store_measurements.assign(1, measurement);
}

RemoveAt from StructArray Ue4

I struggle a bit with deleting struct from my TArray of structs.My struct contains AudioComponent and float.I was using Array.RemoveAt(index), but what i got from this was only removing half of my struct, which is AudioComponent.
Why is that? My function Removing elements looks like this:
void RemoveArrayElement( UAudioComponent AudioComponent )
{
for( int i=0; i<Array.Num(); i++ )
{
if( AudioComponent == Array[i].AudioComponent )
{
Array.RemoveAt( i );
}
}
}
What i want to achieve is completely deleting index, AudioComponent with it's float.
There are few issues with your code. As others mentioned in comments, you should use pointers. And if I'm not mistaken, you aren't allowed to use construction like this:
UPROPERTY()
TArray<UAudioComponent> invalidArray;
You should use UPROPERTY macro, otherwise your properties could and probably will be garbage collected. UPROPERTY wiki.
Next thing is that you are changing array over which you are iterating. I wrote few approaches, let's look at them:
void RemoveArrayElement(UAudioComponent* AudioComponent)
{
TArray<UAudioComponent*> audioArray; // array will be initialized somewhere else, this is for demo purpose.
// you always should check your pointers for validity
if (!AudioComponent || !AudioComponent->IsValidLowLevel() || AudioComponent->IsPendingKill())
return;
// Correct approach 1 (multiple):
TQueue<UAudioComponent*> toDelete;
for (int i = 0; i < audioArray.Num(); i++)
{
auto item = audioArray[i];
if (AudioComponent == item || true) // we simulate another condition for multiselect
{
toDelete.Enqueue(item);
}
}
// better approach for iteration:
for (auto item : audioArray)
if (item == AudioComponent || true) // we simulate another condition for multiselect
toDelete.Enqueue(item);
// finalize deletion in approach 1
UAudioComponent* deleteItem;
while (toDelete.Dequeue(deleteItem))
audioArray.Remove(deleteItem);
// almost correct approach 2 (single) :
UAudioComponent* foundItem;
for (auto item : audioArray)
if (item == AudioComponent)
{
foundItem = item;
break; // we can skip rest - but we must be sure, that items were added to collection using AddUnique(...)
}
if (foundItem)
audioArray.Remove(foundItem);
// correct and the best - approach 3 (single)
audioArray.Remove(AudioComponent);
}
First keep in mind that comparing two objects does not necessarily lead to the expected result of equality. Using the == operator means executing a function (bool operator==(L, R);) that specifies what should happen. So if you did not overload the == operator then you don't know what using it would result to unless you look at the source code where it's defined. Since you want to remove the exact audio component and not an instance of it that looks the same, you want to use pointers in your array. That also helps performance since your are not copying the whole component when calling RemoveArrayElement(...); but a single pointer. Also when there are two identical audio components stored in the array and they are at index a and a+1, then removing the audio component at index a the next iteration would skip your second audio component since all upper indexes are decremented by one.

Pointers/C-Strings in C++. How to filter the strings?

I have an array to filter.
Example:
str = "hellothere" and filter = "eo". What to do when i need to filter?
void filter_str(char* str, char* filter, char*result)
{
while(*str)
{
if() //If the current character in str is one to be filter.
{
*str++;
}
else
{
*result++ = *str++;
}
}
*result = '\0';
}
I just can't figure out how to check if the current character is one that needs to be filter. Since the filter can be more than one character, such as "eo". How do I check both "e" and "o" every loop, and then reset filter back to "e" at the start.
I wanted to make a pointer to the start of filter, then use that at the end of the while to go back to the start of filter. But I am not sure how to make it check *str against all the characters to be filtered.
In this case a function has already been written that will do the hard work for you
if (strchr(filter, *str))
In general this is the answer to any question where you have processing that is too complex for you to handle. Write a function to solve the 'inner' problem, and then use that function in the 'outer' problem. In this case the inner problem is finding a character in a string, and the outer problem is the filtering operation you are doing. You are just lucky that the inner problem has already been solved for you.
If you want to know if a letter is in filter, the "easy" way (without using STL functions) would be to loop through the elements of filter and check each one of them to see if you find the character you are looking for.
while(*str)
{
bool found = false;
// For each element in filter {
// If *str == element {
found = true;
break; // This function gets you out of the 'for' loop
}
}
if(found) //If the current character in str is one to be filter.
{
You can fill up the pseudocode in comments

Working with strcmp and string array

I'm trying to eliminate extra elements in the string array and I wrote the code below. There seems a problem with strcmp function and string arrays. Strcmp doesn't accept the string array elements that way. Can you help me fix that? array3 is string array. I'm coding in C++ and What I want to do is like there are multiple "apple"s or "banana"s in the string array. But I only need one "apple" or one "banana".
for(int l = 0; l<9999; l++)
{
for(int m=l+1;m<10000;m++)
if(!strcmp(array3[l],array3[m]))
{
array3[m]=array3[m+1];
}
}
strcmp returns 0 on equality, so if (strcmp(s1,s2))... means "if the strings are equal then do this...". Is that what you mean?
First of all, you can use operator== to compare strings of std::string type:
std::string a = "asd";
std::string b = "asd";
if(a == b)
{
//do something
}
Second, you have an error in your code, provided 10000 is the size of the array:
array3[m]=array3[m+1];
In this line you are accessing the m+1st element, with m being up to 10000. This means you will eventually try to access the 10001st element, and get out of array bonds.
Finally, your approach is wrong, and this way will not let you remove all the duplicate strings.
A better (but not the best) way to do it is this (pseudocode):
std::string array[];//initial array
std::string result[];//the array without duplicate elements
int resultSize = 0;//The number of unique elements.
bool isUnique = false;//A flag to indicate if the current element is unique.
for( int i = 0; i < array.size; i++ )
{
isUnique = true;//we assume that the element is unique
for( int j = 0; j < result.size; j++ )
{
if( array[i] == result[j] )
{
/*if the result array already contains such an element, it is, obviously,
not unique, and we have no interest in it.*/
isUnique = false;
break;
}
}
//Now, if the isUnique flag is true, which means we didn't find a match in the result array,
//we add the current element into the result array, and increase the count by one.
if( isUnique == true )
{
result[resultSize] = array[i];
resultSize++;
}
}
strcmp works on Cstrings only so if you wanna use it I suggest you alter it to the following: strcmp(array3[l].c_str(),array3[m].c_str()) which makes the strings C Strings.
Another option would be to simply compare them with the equality operator array3[l]==array3[m] this would tell you if the strings are equal or not.
Another way to do what you're trying to do is just to put the array in a set and iterate over it. Sets don't take more than one string of the same content!
References:
More about strcmp :http://en.cppreference.com/w/cpp/string/byte/strcmp
And moreabout c_str: http://en.cppreference.com/w/cpp/string/basic_string/c_str
Regarding String Comparison: http://en.cppreference.com/w/cpp/string/basic_string/compare
C++ Sets http://en.cppreference.com/w/cpp/container/set

PopFront Delimma C++

Strange programming problems as of now..As you can see below i have assigned intFrontPtr to point to the first cell in the array. And intBackPtr to point to the last cell in the array...:
bool quack::popFront( int &popFront )
{
//items[count-1].n = { 9,4,3,2,1,0 };
nPopFront = items[0].n;
if ( count >= maxSize ) return false;
else
{
items[0].n = nPopFront;
intFrontPtr = &items[0].n;
intBackPtr = &items[count-1].n;
}
for (int temp; intFrontPtr < intBackPtr ;)
{
intFrontPtr++;
temp = *intFrontPtr;
*intFrontPtr = temp;
}
--count;
return true;
}
Its just my implementation of a cross between a queue and a stack..PopFront is a public method of the class object quack..The items is a private struct type 'item', it is within the quack.h. It has one member, 'int n'..But, that is irrelevent.
the comment in the code is the contents of my integer array, 'items'.
I am trying to Pop elements off the front of my array. WHat im thinking is that after i get the first item, i'll just incrememnt the frontPtr and transfer the item i got previously to the frontPtr i incremented!...
I cannot, for any reason, use a + or - shift by 1 or the use of stls, boosts, std's and the like..
Can someone help me with my homework assignment?
My suggestion are :
1). Put statement --count where it keeps object's state valid on exceptional condition.
2). clear your concepts of pointers which will help you a lot.
Generally, I would not recommend using an array if you want to pop items off the front. You would be much better off using a linked list, or some other structure which will allow you to remove items in O(1) time. It will be much easier to remove (pop) items this way.
As for your current code, I really can't comment without a better idea of what your class looks like. Please post the class definition at least so we can tell what all your variables are referring to, and what you're code is actually doing.
There are quite a few problems. But I believe your major one is this loop:
for (int temp; intFrontPtr < intBackPtr ;)
{
intFrontPtr++;
temp = *intFrontPtr;
*intFrontPtr = temp;
}
It looks to me like you are trying to shift all your items down. Since this is homework, I'm not going to give you the answer but I'll give you some hints to help debug this.
What you want to do is examine your items array at the beginning and end of the loop.
for (int temp; intFrontPtr < intBackPtr ;)
{
// whats does array look like here
intFrontPtr++;
temp = *intFrontPtr;
*intFrontPtr = temp;
// and what does array look like here
}
If you don't have experience with a debugger, add a function call that will dump your array.