Chapel appears to be focused on n-dimensional arrays and tuples of fixed size. At first sight, there appear to be no dynamic data structures.
One particular issue is that you appear to have to pre-declare the size of associative arrays. Maps and dictionaries in other languages are not restricted in this way.
Does Chapel have a more dynamic map/dictionary type and I just missed it?
First, the answer to your question is yes. The built-in equivalent to a map/dictionary is an associative array in Chapel. See associative arrays primer.
For example, let's declare a dictionary from famous people's names to their birth year.
First, create a domain (ie index set) that will contain the names:
var setOfNames : domain(string); // a domain (set) whose indices are strings
A type declaration of domain(t), where t is some type, creates an associative domain.
Then, create an array over that domain storing an integer age. That in effect creates a map from string -> int.
var nameToBirthYear : [setOfNames] int;
To add somebody to the set, we need to first add them to the domain, and then set their birth year in the array.
setOfNames.add("Thomas Jefferson");
nameToBirthYear["Thomas Jefferson"] = 1743;
setOfNames.add("Alan Turing");
nameToBirthYear["Alan Turing"] = 1912;
Chapel is designed to support multiple arrays over the same domain. So if we wanted to separately also know the place of birth, we could create a separate array to track that.
var nameToBirthPlace : [setOfNames] string;
nameToBirthPlace["Thomas Jefferson"] = "the Colony of Virginia";
nameToBirthPlace["Alan Turing"] = "London, England";
Now, what if we want to add a new famous person?
setOfNames.add("Ada Lovelace");
// note now that both nameToBirthYear and nameToBirthPlace now have
// a value for the key "Ada Lovelace". That new element starts out with
// the default value - so it's 0 and the empty string in this case.
nameToBirthYear["Ada Lovelace"] = 1815;
nameToBirthPlace["Ada Lovelace"] = "London, England";
As a demonstration, we'll loop over the index set and print out the related array elements. (Note that this loop would make more sense with zippered iteration, but I'm trying to keep this example focused on associative arrays and domains).
for name in setOfNames {
var birthYear = nameToBirthYear[name];
var birthPlace = nameToBirthPlace[name];
writeln(name, " started out in ", birthPlace, " in the year ", birthYear);
}
Note that these associative arrays and domains are currently implemented with hashtables. It's possible to create a custom associative array implementation or to create a custom (non-array) data structure for a red-black tree or whatever is needed.
In the future, it might one day be possible to add a key,value pair directly to an associative array (without explicitly mentioning the array's domain). 1-D arrays support such a feature when the domain is not shared by other arrays - see array vector operations primer ).
Related
I want to create a map of vectors. I want the vector to be a private member variable however so when I need to increase the size of the vector for a particular key in the map it does it for all other keys in the map also(would that work?). This will be a map of vectors(of ints) where the keys are strings. My question is how to access a particular element in the vector to change is value in C++. Something along the lines of map_name['word'].[3] = 2 if i wanted to set the third value of the vector of "word" to 2.
enter image description here
enter image description here
Im still having trouble figuring out how to make it so the size of each vector for all the keys in the maps is modifiable so i can increase the size of each vector at any point along the program. This is b/c the vector size is unknown at runtime and iterating through each element in the map to change the vector size will take too long.
The pattern is recursive.
That is, when you do:
expression[key] = value;
your expression doesn't have to just be a variable name; it can be a more complex expression, such as map_name["word"].
So:
map_name["word"][3] = 2;
Regarding the first question, yes it is possible as mentioned in one of the comments, you can make your imaginary class to do that.
And in the second question, you'll have to access an element of a vector which is an element of a map like this:
map1["abc"][1] = 2
The '.' you added was unnecessary because you're accessing an element inside another element, just like a 2D array
For example I am making a Pacman game and I am using a struct array to represent the ghosts.
But is there any way to change the ghost[0] expression to Inky ?
It seems you are looking for associative array. Associative array is an array that can be accessed with something like association. For example, if you want to access your fruits array and get the apple, you could do: fruits["apple"] and get the value, instead of wondering which index the apple was.
If this is what you are really looking for, then in C++ it is called a map. The map is the same as associative array. Take a look onto how to use it.
https://en.cppreference.com/w/cpp/container/map
You can define a reference to any item in your struct array.
Example:
Ghost &inky = ghosts[0];
Ghost &blinky = ghosts[1];
Ghost &pinky = ghosts[2];
Ghost &clyde = ghosts[3];
To respect C++ convention, I recommand that all these references are defined with a name that begin with a lower case.
You can then use all these references as normal variables using . to call member's functions or to read or assign member's variables.
Example:
inky.setBackColor(blue);
inky.remove();
clyde.size += 2;
So I'm trying to create an empty Array that is the length of a table row. I know how to get the length of a row, but I haven't got a clue in how to make an array with a pre-defined length. The program i'm making is dynamic so the length of the array will vary depending on the table I'm accessing.
Does anyone know how?
You've said you want an empty array, so take a look at Array.zeroCreate<'T>.
From the documentation:
Creates an array where the entries are initially the default value
Unchecked.defaultof<'T>.
Example:
let arrayOfTenZeroes : int array = Array.zeroCreate 10
This page has a lot of useful information on F# arrays - have look through it, it should point you in the right direction.
As Panagiotis Kanavos has pointed out in comments, F# differs from a language like C# for array creation, so I will quote directly from the F# language reference article I've linked to above for clarity:
Several functions create arrays without requiring an existing array.
Array.empty creates a new array that does not contain any elements.
Array.create creates an array of a specified size and sets all the
elements to provided values. Array.init creates an array, given a
dimension and a function to generate the elements. Array.zeroCreate
creates an array in which all the elements are initialized to the zero
value for the array's type.
PROBLEM:
I have a Hashtable in which I store some names. My problem is to print the content at each index in alphabetic order.
NOTE:
I'm working in C++, and it's required not to use any predefined C++ functions. (I defined the Hashtable using a struct, then declared all the usual functions for Hashtable).
MY IDEA:
I thought of using an array, such that I could copy all the records, stored in the linked list at index "i" of Hashtable, in it (array), then sort the array and, finally, print it's content. So, in such a way for all indexes, where the head of respective linked list in not null pointer.
I think this idea is to primitive. Can you, please, give me any suggestion on this topic ?
Thank you in advance !
If your data structure is an associative container but it's not sorted (eg std::map vs std::unordered_map) then you have no way to keep them ordered while managing the structure only.
Many hash table implementation are not even able to provide random access operators, since it makes no sense for such data structure: although indices are internally required to address buckets for values they are not meaningful from a client point of view.
Your primitive idea seems reasonable, copy the keys into a vector / linked list / array and then sort the array.
I get a structure, and I don't know the size of it (every time it's different). I would like to set the last place in one of the fields of this structure to a certain value. In pseudocode, I mean something like this:
structureA.fieldB[end] = cert_value;
I'd do it in matlab however I cannot somehow find the proper syntax in c++, can you help me?
In Matlab, a structure data type holds key-value pairs where the "value" may be of different types. In C++, there are some key-value containers available (associative containers like set, map, multimap), but they usually store elements of a single type. What you need if I understood it right is something like
"one" : 1
"two" : [1,2,5]
"three" : "name"
Which means that your structure resembles a Python dictionary.
In C++, the only way I have heard of using containers with truly different types is by using boost::any, which is accepted as the answer to this question.
If you pack a container with elements of different types, then you can use the end() member function of a container to get the last element.
You need sizeof, this gives you the size of the array in bytes. Since you want the the index of the last element, you have to divide this number by the number of bytes for one element. You end up with:
int index_end = sizeof(structureA.fieldB) / sizeof(structureA.fieldB[0]);
structureA.fieldB[index_end] = new_value;