I am trying to perform a few simple tasks with an array of structures that I have and feel like I'm almost done with my solution but am having some last minute trouble. I am trying to accomplish the following tasks:
Create a struct with the following values; id, name, int arr[].
I am using a FOR loop to iterate over an array of values like ID, name, sub id.
For each item in my list, I am trying to make the decision if I've seen the struct before and if its in my agencies Array.
If its not there, add the current struct to an array. If its already present in the array then add the current sub id to the int arr[] entry of the struct.
When I run my code below I keep getting the error, "BigDecimal cannot be used as an array" and I don't understand what's happening. I am new to CFSCRIPT so perhaps I'm either not getting the arr[] values out of the struct or not defining my struct correct so the third value is of Array type.
remote array function getCurrAgenciesList(String Acct_Id) returnformat="JSON"
{
include "qry_getCurrentAssignedRepoAgenciesAll.cfm";
//define arr to hold values...
var agenciesArr = [];
var recordLength = getCurrentAssignedRepoAgencies.RecordCount;
for(agency in getCurrentAssignedRepoAgencies)
{
currentStruct = {id=agency.repoID, name=agency.repoName, relatedColl=agency.collatSub};
var structArrIndex = arrayOfStructsFind(agenciesArr, "id", agency.repoID);
if(structArrIndex eq 0)
{
//add new struct to agenciesArr
ArrayAppend(agenciesArr,currentStruct,"true");
}
else
{
//find current struct in array using index from before...
var collFromStr = agenciesArr[structArrIndex]['relatedColl'];
//add current collatsub to array, append.
var updatedStruct = ArrayAppend(collFromStr,agency.collatSub);
//reassign updated arr[] struct value back in array.
agenciesArr[structArrIndex]['relatedColl'] = collFromStr;
}
}
//return...
return agenciesArr;
}
function arrayOfStructsFind(Array, SearchKey, Value)
{
var result = 0;
var i = 1;
var key = "";
for (i=1;i lte arrayLen(array);i=i+1)
{
for (key in array[i])
{
if(array[i][key]==Value and key == SearchKey)
{
result = i;
return result;
}
}
}
return result;
}
Any help would be greatly appreciated, as I feel I'm stuck on this one last thing or there's something I am missing. Any feedback is welcome.
UPDATE the error happens at line 27,
var updatedStruct = ArrayAppend(collFromStr,agency.collatsub);
UPDATE 3:39PM
I believe the issue is not related to the above line but this line:
var collFromStr = agenciesArr[structArrOmdex]['relatedColl'];
I am asking for an array to be returned from the struct from key, relatedColl. I am thinking only an integer is return so when the next Array Append operation is performed the code explodes. So, how does one create an array inside a struct in Cold Fusion\CFSCRIPT????
I have solved my problem by making the following changes:
Re-defined the struct definition to have an array type as the third element.
After doing this it looks like the search needed to be modified so I switched the ordering of my key, value if statement.
I also gathered a great amount of information from this link. It is wonderful.
Final Code:
remote array function getCurrAgenciesList(String Acct_Id) returnformat="JSON"
{
include "qry_getCurrentAssignedRepoAgenciesAll.cfm";
//define arr to hold values...
var agenciesArr = [];
var recordLength = getCurrentAssignedRepoAgencies.RecordCount;
for(agency in getCurrentAssignedRepoAgencies)
{
arr = [agency.collatSub];
currentStruct = {id=agency.repoID, name=agency.repoName, relatedColl=arr};
var structArrIndex = arrayOfStructsFind(agenciesArr, "id", agency.repoID);
if(structArrIndex eq 0)
{
//add new struct to agenciesArr
ArrayAppend(agenciesArr,currentStruct,"true");
}
else
{
//find current struct in array using index from before...
var collFromStr = agenciesArr[structArrIndex]['relatedColl'];
//add current collatsub to array, append.
ArrayAppend(collFromStr,agency.collatSub,"true");
//reassign updated arr[] struct value back in array.
agenciesArr[structArrIndex]['relatedColl'] = collFromStr;
}
}
//return...
return agenciesArr;
}
function arrayOfStructsFind(Array, SearchKey, Value)
{
var result = 0;
var i = 1;
var key = "";
for (i=1;i lte arrayLen(array);i=i+1)
{
for (key in array[i])
{
if(key == SearchKey and array[i][key]==Value)
{
result = i;
return result;
}
}
}
return result;
}
Related
If I have array string for courses name like
courseName = {"java","math","physics"}
and enum have constant variables with code for courses like
CSC = 320
How to associate them in C language ?
You need some way to map the enumeration to the array index.
A simple array of structures with a "from" and "to" member solve it:
struct
{
int course; // Course enumeration value
unsigned name; // Name array index
} course_to_name_map[] = {
{ JAVA_101, 0 },
// etc...
};
To find the name loop over the mapping array to find the course, and then use the corresponding index to get the name:
char *get_course_name(int course)
{
static const size_t map_element_count = sizeof course_to_name_map / sizeof course_to_name_map[0];
for (unsigned i = 0; i < map_element_count; ++i)
{
if (course_to_name_map[i].course == course)
{
return course_names[course_to_name_map[i].name];
}
}
// Course was not found
return NULL;
}
Note that this is only one possible solution. It's simple but not very effective.
why not:
enum KEY {
KEY_JAVA = 320,
KEY_MATH = 123,
KEY_PHYSICS = 17,
};
char *course_to_name[] = {
[KEY_JAVA] = "java",
[KEY_MATH] = "math",
{KEY_PHYSIC] = "physics",
};
// usage:
course_to_name[KEY_JAVA];
It works quite well as long as courses codes are relatively small.
I have to copy paste this exact code below into 3 separate functions (juice function, milk function and buy function). So I thought, why not make another function called array_checker and call it in toe juice, milk and buy function instead of the copy pasting the code. However, the function (copy pasted code) needs to return 2 things. int item_used and int buy_now. How can I do this?
This is the code I copy paste:
if (item_sale == 1) {
item_used = TRUE;
buy_now = legal_cards[0];
} else {
item_used = FALSE;
}
There are two general approaches to this:
Create a struct with two int members to return from your function - this is fine when two values that you return are easy to copy, e.g. a pair of ints, or
Take a pointer for one or both variables - this lets you avoid copying, but requires the caller to allocate storage for the result upfront.
Here is an example of the first approach:
struct buy_decision {
int item_used;
int buy_now;
};
buy_decision milk(...) {
buy_decision res;
if (item_sale == 1) {
res.item_used = TRUE;
res.buy_now = legal_cards[0];
} else {
res.item_used = FALSE;
res.buy_now = 0;
}
return res;
}
Here is an example of the second approach with buy_now taken by pointer:
int milk(..., int* buy_now_ptr) {
if (item_sale == 1) {
*buy_now_ptr = legal_cards[0];
return TRUE;
}
return FALSE;
}
Well, you can return an array with both numbers.
To return multiple values from a function, create one structure, put the member whatever you want into this & return the structure variable. for e.g
typedef struct buy_fun_info {
int item_used;
int buy_now;
}BUY;
In array_checker() function, create the variable of above structure, fill the members & return those. for e.g
BUY array_checker() { /*array_checker() function */
BUY obj;
obj.buy_now = legal_cards[0];
obj.item_used = FALSE;
return obj;/* return structure variable */
}
Above I tried to explain with sample example, you need to modify accordingly.
You have to either define a structure to return :
struct itemStuff {
int itemUsed;
int buy_now;
}
then
struct itemStuff myItemFunction(...) {
struct itemStuff myItem;
(...)
if (item_sale == 1) {
myItem.item_used = TRUE;
myItem.buy_now = legal_cards[0];
} else {
myItem.item_used = FALSE;
}
return myItem;
}
The caller of the function will have to create the same struct to receive the return data
struct itemStuff thisItem = myItemFunction(...);
or use pass-by reference to pass in modifiable arguments
void myItemFunction(..., int *item_used, int *buy_noe) {
if (item_sale == 1) {
*item_used = TRUE;
*buy_now = legal_cards[0];
} else {
*item_used = FALSE;
}
}
Here, the caller will have to pass in the address of two integers to be set :
int used;
int buy;
myItemFunction(..., &used, &buy);
I'm new in C programming. I'm developing a priority queue in C'99 with the heap data structure.
I'm using heapifyDown() in combination with swapValues() to sort the heap array for extracting the first element (min-heap) pqueue_extractMin() function. My structure looks like this:
typedef struct ProrityQueue_s PriorityQueue;
typedef struct PriorityQueue_Entry_s *PriorityQueue_Entry;
struct ProrityQueue_s {
int size, last;
char error;
PriorityQueue_Entry *entries;
};
struct PriorityQueue_Entry_s {
char *value;
float priority;
};
For information – Full code for information on gist: https://gist.github.com/it4need/ddf9014bfda9fe6a64bb01a7417422bc
Questions:
Insertion into the Priority queue ("minheap") looks good. Everything is fine. But when I'm extract more than one element at once, I will get this error: "Process finished with exit code 11".
Is this line allowed to copy the whole contents of the last element to the first of the heap? priorityqueue->entries[0] = priorityqueue->entries[priorityqueue->last];
swapValues(priorityqueue, currentPositionIndex, smallestChild); Can I swap values of whole Structure elements? -> implementation (bottom).
HeapifyDown():
void heapifyDown(PriorityQueue *priorityqueue)
{
int currentPositionIndex = 0;
while(currentPositionIndex < priorityqueue->last)
{
int smallestChild = currentPositionIndex;
int leftChildIndex = (2 * currentPositionIndex) + 1;
int rightChildIndex = (2 * currentPositionIndex) + 2;
smallestChild = (priorityqueue->entries[leftChildIndex]->priority < priorityqueue->entries[smallestChild]->priority && priorityqueue->last > leftChildIndex)
? leftChildIndex : smallestChild;
smallestChild = (priorityqueue->entries[rightChildIndex]->priority < priorityqueue->entries[smallestChild]->priority && priorityqueue->last > rightChildIndex)
? rightChildIndex : smallestChild;
if(smallestChild == currentPositionIndex)
{
break;
}
swapValues(priorityqueue, currentPositionIndex, smallestChild); // #todo: Why does this line break the function on two function calls by negative values
currentPositionIndex = smallestChild;
}
}
SwapValues():
void swapValues(PriorityQueue *priorityqueue, int firstIndex, int secondIndex)
{
// #todo: Does this work properly?
PriorityQueue_Entry tmp_entry = priorityqueue->entries[firstIndex];
priorityqueue->entries[firstIndex] = priorityqueue->entries[secondIndex];
priorityqueue->entries[secondIndex] = tmp_entry;
}
extractMin():
char *pqueue_extractMin(PriorityQueue *priorityqueue)
{
if(isEmpty(priorityqueue))
{
priorityqueue->error = ERROR_PRIORITY_QUEUE_EMPTY;
}
priorityqueue->last--;
char *tmp = priorityqueue->entries[0]->value;
priorityqueue->entries[0] = priorityqueue->entries[priorityqueue->last]; // #todo: Is this allowed?
heapifyDown(priorityqueue); // #todo: Why does this line break the extractMin() function on two function calls -> check swapValues() in heapifyDown()
return tmp;
}
Full code for information on gist: https://gist.github.com/it4need/ddf9014bfda9fe6a64bb01a7417422bc
I have an struct which defines an array of structs, each of which contain a couple more arrays. These inner arrays define my 'datasets'.
In numerous places, I wish to iterate over all the datasets. To avoid 3 nested loops, I loop over the total number of datasets and have a few if statements to keep track of which array I need to access. It looks like this:
int datasetCount = 0;
int defendedDatasetCount = 0;
int i;
Dataset *ds;
for (i = 0 ; i < totalDatasets ; i++)
{
// If we have passed the number of datasets in this group, move to the next group
if (datasetCount == (dg->nDatasets + dg->nDefDatasets))
{
dg++;
datasetCount = 0;
defendedDatasetCount = 0;
}
// If we have gone through all the (undefended) datasets, read from thte defended datasets
if (datasetCount >= dg->nDatasets)
{
ds = &(dg->defDatasets[defendedDatasetCount]);
defendedDatasetCount++;
}
else
{
ds = &(dg->datasets[datasetCount]);
}
where dg is the pointer to a struct which is simply an array of structs and a size counter.
I find myself repeating this boilerplate code for iterating through the datasets in a few functions which do different things.
I'm struggling to be able to come up with something like this:
while (give_me_next_dataset(dg) == TRUE)
{
...
}
is it possible?
It's possible, but the proposed API isn't very nice. You're going to have to put iteration state somewhere, and you're not leaving any room for that.
I would propose something like:
struct DgIter {
struct Dg *dg;
size_t index;
size_t dataSet;
};
Then you can have functions like:
struct DgIter iter_start(struct Dg *dg)
{
const struct DgIter iter = { dg, 0, 0 };
return iter;
}
void * iter_next_dataset(struct DgIter *iter)
{
// check if there is a current dataset, else return NULL
// update fields in iter as necessary
}
I have a programming question in C where I am trying to design a List and add an element at a given index.
Here is my insertElement method:
ListElement* getNextElement(ListElement *listElement){
return listElement->nextElement;
}
/* Insert a given element at the specified index in a specified list. Shifts
* all other elements to the right, increasing their index by 1.
* Requires 0 <= index <= listSize(), otherwise the element should not be inserted.
*/
void insertElement(List *list, ListElement *listElement, int index) {
ListElement* tempElement = list->headElement;
int count = 0;
while (tempElement != NULL) {
if (count == index) {
}
tempElement = getNextElement(tempElement);
count++;
}
}
But I don't actually know how to shift over and insert the element.
Here is how I attempt to insert:
int main() {
ListElement* newElement = malloc(sizeof(ListElement));
insertElement(&myList, newElement, 1);
exit(EXIT_SUCCESS);
}
Can anybody help me out? Thanks in advance.
The beauty of a linked list is that, unlike an array, you don't need to shift or move anything in order to do an insert.
Assume your list is A->C and you want to insert B after A to give A->B->C.
A->nextElement is set to C; that needs to change.
B->nextElement is not set; that needs to change.
You should be able to see how to accomplish that with what you're given.