D: How create array of Tuples? - tuples

I am looking at docs and can't understand hot can I create array of Tuples. It's compile fine:
auto myDataTuple = tuple(url, path);
but this code produce error:
auto myDataTuples [] ~= myDataTuple;
Error: no identifier for declarator myDataTuples[].
It's can't understand type for myDataTuples or what?

You can't append to a declaration since it doesn't exist yet.
The type tuple(x, y) returns is Tuple!(typeof(x), typeof(y)). You can make an array of them. So if url and path are both strings, try:
Tuple!(string, string)[] myDataTuple; // the [] makes an array
myDataTuple ~= tuple(url, path);
PS: it is my opinion that structs are better than tuples basically all the time. (a Tuple is just a generated struct anyway). You can probably also do struct MyData { string url; string path; } and use MyData everywhere too. It is easier to realize what it is later.

To define an array using a set of existing variables and values you can list them inside braces [] and declare the array just like an ordinary variable:
string url, path;
auto myDataTuple = tuple(url, path);
auto myDataTuples = [myDataTuple];
// Print out the type for better understanding: Tuple!(string, string)[]
writeln(typeof(myDataTuples).stringof);
This creates a new dynamic array with one element that can be append to.
Appending to an existing array works like this:
// Append an item (variable and literal)
myDataTuples ~= anotherTuple;
myDataTuples ~= tuple(url2, path2);
// Append an array (variable and literal)
myDataTuples ~= anotherArray;
myDataTuples ~= [tuple(url3, path3), tuple(url4, path4)];

Related

How can I copy an element of vector<string> into a string?

I've tried to copy like below.
I met crash, though.
Isn't it possible to use the assignment operator at this time?
std::vector<std::string> string_list;
std::string str;
string_list[0] = "abc";
str = string_list[0];
Your vector is empty, therefore attempting to access the first element will result in a crash. You can initialize a vector like so:
std::vector<std::string> list = {"my string"};
std::string s = list[0];
Or if you prefer to dynamically grow the list you can do:
std::vector<std::string> list;
list.push_back("my string");
std::string s = list[0];
Your vector of strings string_list
std::vector<std::string> string_list;
is empty, i.e., it contains no element, no string at all, size() on that std::vector will return zero.
Then, in the statement:
string_list[0] = "abc";
You are writing to an element of the vector that does not exist and that results in undefined behavior (in your case, the program crashes).
Try initializing the vector in the following way instead:
std::vector<std::string> string_list(1);
This way, the vector string_list will contain a single empty string (i.e., a default constructed std::string object), which you can access using the operator[] (as you already did) on your vector of strings string_list:
string_list[0] = "abc";
By doing this, you are using the assignment operator of that empty string.
Since, your vector is empty, you might get a crash when you attempt to access string_list[0] because you are trying to alter/access something that isn't there in the first place.
You can take care of it in two ways :
std::vector<std::string> string_list(10) Mention a non-zero size while declaring the vector( such as 10 ). That way the vector of strings will consists of 10 empty strings inside the vector.
Use string_list.push_back("abc"). This will dynamically allocate memory for your vector even if you don't explicitly declare the vector with a given size.
Option 1 :
std::vector<std::string> string_list(10);
string_list[0] = "abc"; // This is okay.
Options 2 :
std::vector<std::string> string_list; // Note that no size mentioned here.
string_list.push_back("abc"); //This is okay as well. :)

c++ initialize array with each element reference?

I'm a c++ beginner, I want to initialize an array so that the element of the array is actually a reference to a variable.
string string_1;
string string_2;
string strings[2] = {&string_1, &string_2};
Is this allowed? So any operation done to the array will be applied to the variables string_1 and string_2 themselves?
You can simulate an array of references:
using s_ref = std::reference_wrapper<std::string>;
s_ref strings[] = { std::ref(string_1), std::ref(string_2) };
Or just use pointers (that's really what reference_wrapper does underneath).

Is there a literal for the empty array in Chapel?

I'm trying to make an empty array in Chapel. An array of one element can be made like this:
var a: [1..1] int = (1);
But when I try
var b: [1..0] int = ();
I get
syntax error: near ')'
Is there an empty array literal in Chapel? I haven't been able to find an example.
EDIT
The reason I am trying to get an empty array is that I would like to implement get this function working for empty arrays:
proc sum_of_even_squares(a) {
// Does this work for empty arrays? Probably not.
return + reduce ([x in a] if x % 2 == 0 then x*x else 0);
}
assert(sum_of_even_squares([7]) == 0);
assert(sum_of_even_squares([7, 3]) == 0);
assert(sum_of_even_squares([7, 3, -8]) == 64);
assert(sum_of_even_squares([7, 3, -8, 4]) == 80);
But I am unable to form an empty array literal.
Generally, in Chapel, to declare an empty thing, you specify its type but no initialization, such as
var i:int;
But to declare an integer initialized with a value, you'd probably leave off the type:
var j = 2;
In this case, simply omitting the initializer makes it work.
var b: [1..0] int;
Relatedly, (1) is not declaring an array literal but rather a tuple literal. The syntax [1] would declare an array literal. At present, zero-length tuples are not supported in the compiler implementation. It might be easier to get zero-length array literals to work, but it doesn't seem to work right now either (in 1.15).
And how would a zero-length array literal know the type of the elements? For this reason I don't think it could help in your specific case.

How to set std::vector<std::string> with custom string in each element

i have configuration that i need to set into some kind of container
i try to set into std::vector
but im getting compilation errors in both ways:
std::vector<std::string> ConfigVec= new std::vector<std::string>();
ConfigVec->at(0).append("00000\
11111\
00000");
ConfigVec->at(1) = "11111\
00000\
00000";
what is the shortst way to do that without to many std::string declarations
First, drop the pointers and new1. Second, you are appending to elements that don't exist. Push strings back into the vector.
std::vector<std::string> ConfigVec;
ConfigVec.push_back("000001111100000");
ConfigVec.push_back("111110000000000");
and so on.
If you have a small number of strings, you can initialize the vector directly (unless you're stuck with a pre-C++11 implementation):
std::vector<std::string> ConfigVec{"000001111100000", "111110000000000"};
1 * You were using ConfigVec as a pointer (assigning the result of new to it, and using -> to access its members), but it isn't actually declared as one. This in itself is an error. In any case, there is little case for using new and raw pointers to dynamically allocated resources in C++.
std::vector<std::string> ConfigVec= new std::vector<std::string>();
This is "java-nese": std::vector<std::string> ConfigVec is just a vectcor of string itself.
ConfigVect.push_back("text") will just add a string at the end.
Or did you mean
std::vector<std::string>* ConfigVec= new std::vector<std::string>();
//----------------------^-----------<< note taht!
In any case you cannot use at (or []) on an empty vector, unlsess you first size it appropriately

Inserting into an Associative array?

I'm playing around with associative arrays right now and I can't
seem to figure out how to add additional objects to the array. I
tried insert but it doesn't recognize both arguments.
Also, if I do this it produces an error:
Node[bool] test;
Node node;
Node[bool] temp = [ false:node ];
test ~= temp;
//Error 1 Error: cannot append type Node[bool] to type
//Node[bool] C:\Users\CP\Documents\Visual Studio
//2010\Projects\D\STDS\NPC.d 256
Does this mean you can't use the append operator on associative
arrays ?
To add a single element, just assign it like you would for any other type of array.
test[false] = node;
To append an assoc array to another assoc array, loop over it, and reassign the elements.
foreach(k, v; temp) test[k] = v;
The why: Associative arrays are not lists; as the name suggests, they are, well, associative arrays. The append operator would make sense for consecutive list of elements. D's AAs are hash tables.
Are you looking for an array of associative arrays? In that case, the following would work, as an example:
struct Node { int x; }
Node[bool][] test;
Node[bool] temp = [ false:Node(1), true:Node(2) ];
test ~= temp;
test ~= [ false:Node(3), true:Node(4) ];
writefln("Nodes: %s", test); // Nodes: [[false:Node(1), true:Node(2)], [false:Node(3), true:Node(4)]]
Which would give you a linear array (test), each element of which is an associative array with a maximum of two elements (since your key type is bool).
However, are you trying to create a binary tree instead? Then you'd want Node member variables inside the Node struct itself for the left and right branches (please disregard if this isn't the case).