The following is an example of a multi-dimensional array declaration in C#:
var Number = new double[2, 3, 5]
{
{
{ 12.44, 525.38, -6.28, 2448.32, 632.04 },
{-378.05, 48.14, 634.18, 762.48, 83.02 },
{ 64.92, -7.44, 86.74, -534.60, 386.73 }
},
{
{ 48.02, 120.44, 38.62, 526.82, 1704.62 },
{ 56.85, 105.48, 363.31, 172.62, 128.48 },
{ 906.68, 47.12, -166.07, 4444.26, 408.62 }
},
};
I would like to do the same in C++, but do not know how and have not read my C++ book.
How can I accomplish this?
Here is a naive way of doing that without explicitly specifying the bounds:
vector<vector<vector<double>>> v =
{
{
{ 12.44, 525.38, -6.28, 2448.32, 632.04 },
{-378.05, 48.14, 634.18, 762.48, 83.02 },
{ 64.92, -7.44, 86.74, -534.60, 386.73 }
},
{
{ 48.02, 120.44, 38.62, 526.82, 1704.62 },
{ 56.85, 105.48, 363.31, 172.62, 128.48 },
{ 906.68, 47.12, -166.07, 4444.26, 408.62 }
},
};
However, the vector of vectors will allow you to push elements into each dimension freely (they are just independent vectors), so you might end up not having a consistent multi-dimensional vector. In particular, the compiler won't detect any attempt to put more or less elements into one dimension than into another one.
If that is a concern, you might want to check Boost.MultiArray.
You don't need the standard library, or Boost, to define and initialize a fixed size multidimensional array.
double Number[2][3][5] =
{
{
{ 12.44, 525.38, -6.28, 2448.32, 632.04 },
{-378.05, 48.14, 634.18, 762.48, 83.02 },
{ 64.92, -7.44, 86.74, -534.60, 386.73 }
},
{
{ 48.02, 120.44, 38.62, 526.82, 1704.62 },
{ 56.85, 105.48, 363.31, 172.62, 128.48 },
{ 906.68, 47.12, -166.07, 4444.26, 408.62 }
},
};
Related
I have a nested json with the following structure within UE4:
{
"boundary_points__per__cell": {
"0": [{
"x": 16.451330042628662,
"y": 2.0813326861577965
},
{
"x": 16.755262971791506,
"y": 2.0406535171257136
}
],
"1": [{
"x": -1.6378002918100634,
"y": 4.9689057223409412
},
{
"x": 0.9452331911724825,
"y": 6.1469903490163311
}
]
}
}
I tried using proposed techniques from other threads that suggest using the JsonObjectStringToUStruct. In particular I have the following structs to parse the json logic:
USTRUCT()
struct FBoundaryPoint
{
GENERATED_USTRUCT_BODY()
UPROPERTY()
int32 x;
UPROPERTY()
int32 y;
};
USTRUCT()
struct FBoundaryPoints
{
GENERATED_USTRUCT_BODY()
UPROPERTY()
TArray<FBoundaryPoint> BoundaryPoints;
};
USTRUCT()
struct FVoronoiStruct
{
GENERATED_USTRUCT_BODY()
UPROPERTY()
TMap<FString, FBoundaryPoints> boundary_points__per__cell;
};
However, although I can receive the key strings (e.g "0", "1") I am unable to extract the values of the json array. The boundary points dictionary contains only 2 keys ("0", "1") for the sake of the question. In a real scenario it will contain a lot more than the presented case.
Any help will be appreciated.
Firstly, those aren't integers, so you would probably want to use float or double instead of int32.
On the topic of why it won't parse, based on a comment by nick.shin:
the use of TMap is not applicable to JSON -- the simpler TArray must be used.
and, to give you the closest "TMap-like" functionality -- your JSON will need to look like:
{
"boundary_points__per__cell": [
{ "key":"0", "value":[{ "x":16.451330042628662, "y":2.0813326861577965 }] },
{ "key":"1", "value":[{ "x":16.755262971791506, "y":2.0406535171257136 }] }
]
}
When using JsonObjectConverter -- the engine will NOT allow you to make up a "key" name "on-the-fly" -- you need to define it so the engine can make the properties accessible as standard C++ structs (which makes it possible to setup and be used with Blueprints).
having said that, it is possible to make your own key:value pairs -- but, you will need to use the more low level TJsonWriter and TJsonWriterFactory & TJsonReader and TJsonReaderFactory functions. you will need to hold the engine's hand when you fill your own USTRUCT that may be using TMap...
and then, your custom JSON parser and writer can read something like this:
{
"MyMap": [
{ "MyKey1", { "0", "bliz" } },
{ "MyKey2", { "1", "blaz" } }
]
}
how can I find duplicate values on a list,
Let's say I got a List like this:
List<Map<String, dynamic>> users = [
{ "name": 'John', 'age': 18 },
{ "name": 'Jane', 'age': 21 },
{ "name": 'Mary', 'age': 23 },
{ "name": 'Mary', 'age': 27 },
];
How I can iterate the list to know if there are users with the same name?
A simple way would be this:
void main() {
List<Map<String, dynamic>> users = [
{ "name": 'John', 'age': 18 },
{ "name": 'Jane', 'age': 21 },
{ "name": 'Mary', 'age': 23 },
{ "name": 'Mary', 'age': 27 },
];
List names = []; // List();
users.forEach((u){
if (names.contains(u["name"])) print("duplicate ${u["name"]}");
else names.add(u["name"]);
});
}
Result:
duplicate Mary
Probably a cleaner solution with extensions.
By declaring:
extension ListExtensions<E> on List<E> {
List<E> removeAll(Iterable<E> allToRemove) {
if (allToRemove == null) {
return this;
} else {
allToRemove.forEach((element) {
this.remove(element);
});
return this;
}
}
List<E> getDupes() {
List<E> dupes = List.from(this);
dupes.removeAll(this.toSet().toList());
return dupes;
}
}
then you can find your duplicates by calling List.getDupes()
Note that the function removeAll doesn't exist in my current Dart library, in case you're reading this when they implement it somehow.
Also keep in mind the equals() function. In a List<String>, ["Rafa", "rafa"] doesn't contain duplicates.
If you indeed want to achieve this level of refinement, you'd have to apply a distinctBy function:
extension ListExtensions<E> on List<E> {
List<E> removeAll(Iterable<E> allToRemove) {
if (allToRemove == null) {
return this;
} else {
allToRemove.forEach((element) {
this.remove(element);
});
return this;
}
}
List<E> distinctBy(predicate(E selector)) {
HashSet set = HashSet();
List<E> list = [];
toList().forEach((e) {
dynamic key = predicate(e);
if (set.add(key)) {
list.add(e);
}
});
return list;
}
List<E> getDupes({E Function(E) distinctBy}) {
List<E> dupes = List.from(this);
if (distinctBy == null) {
dupes.removeAll(this.toSet().toList());
} else {
dupes.removeAll(this.distinctBy(distinctBy).toSet().toList());
}
return dupes;
}
}
I had a feeling Rafael's answer had code similar to Kotlin so I dug around and saw that these functions are part of the kt_dart library which basically gets the Kotlin standard library and ports it to Dart.
I come from a Kotlin background so I use this package often. If you use it, you can simply make the extension this much shorter:
extension KtListExtensions<T> on KtList<T> {
KtList<T> get duplicates => toMutableList()..removeAll(toSet().toList());
}
just make sure to add kt_dart on your pubspec: kt_dart: ^0.8.0
Example
final list = ['apples', 'oranges', 'bananas', 'apples'].toImmutableList();
final duplicates = list.duplicates; // should be ['apples'] in the form of an ImmutableList<String>
void main() {
List<String> country = [
"Nepal",
"Nepal",
"USA",
"Canada",
"Canada",
"China",
"Russia",
];
List DupCountry = [];
country.forEach((dup){
if(DupCountry.contains(dup)){
print("Duplicate in List= ${dup}");
}
else{
DupCountry.add(dup);
}
});
}
I am trying to create a function that counts the people of each category that have a value bigger than 0. If this is my data...
DATA.CSV
name; category; value
name1; A; 10
name2; A; 0
name3; A; 5
name4; B; 7
name5; B; 3
name6; C; 0
...I should get the following results
count(dataset, "A")=2
count(dataset, "B")=2
count(dataset, "C")=0
EDIT! I am actually loading data from a .json file
[
{
"voce":"amministrazione",
"categoria":"funzioni",
"val2015":404571081
},
{
"voce":"sociale",
"categoria":"funzioni",
"val2015":235251679
},
{
"voce":"territorio e ambiente",
"categoria":"funzioni",
"val2015":286164667
},
{
"voce":"viabilità e trasporti ",
"categoria":"funzioni",
"val2015":144185664
},
{
"voce":"istruzione",
"categoria":"funzioni",
"val2015":168774925
},
{
"voce":"cultura ",
"categoria":"funzioni",
"val2015":55868045
},
{
"voce":"sport",
"categoria":"funzioni",
"val2015":27219432
},
{
"voce":"turismo",
"categoria":"funzioni",
"val2015":9544845
},
{
"voce":"sviluppo economico",
"categoria":"funzioni",
"val2015":14790363
},
{
"voce":"servizi produttivi",
"categoria":"funzioni",
"val2015":4334
},
{
"voce":"polizia locale",
"categoria":"funzioni",
"val2015":99007202
},
{
"voce":"giustizia ",
"categoria":"funzioni",
"val2015":12147068
},
{
"voce":"anticipazioni di cassa",
"categoria":"rimborso prestiti",
"val2015":304323808
},
{
"voce":"finanziamenti a breve termine",
"categoria":"rimborso prestiti",
"val2015":0
},
{
"voce":"prestiti obbligazionari",
"categoria":"rimborso prestiti",
"val2015":38842996
},
{
"voce":"quota capitale di debiti pluriennali",
"categoria":"rimborso prestiti",
"val2015":0
},
{
"voce":"quota capitale di mutui e prestiti",
"categoria":"rimborso prestiti",
"val2015":128508755
},
{
"voce":"spese per conto terzi",
"categoria":"",
"val2015":232661261
},
{
"voce":"disavanzo di amministrazione",
"categoria":"",
"val2015":0
}
]
I tried a for loop with an if statement inside but it is not working.
function count (dataset, chosenCategory) {
var count = 0;
for (d in dataset) {
if (d.categoria==chosenCategory && d.val2015>0) {
count += 1;
} else {
count += 0;
}
}
}
What am I doing wrong?
have you tried changing "d.value" to "+d.value"?
If they're from a csv file, values are generally loaded as strings, so everything you want to treat as a number needs converted to a number, and the '+' does that.
try it in your console
"1">0
false
+"1">0
true
PS. You don't need the else condition
If I have two map<string, int>s how can I swap an element from each map?
For example:
map<string, int> ps{ { "triangle", 0 }, { "cross", 1 }, { "square", 2 }, { "circle", 3 } };
map<string, int> xbox{ { "y", 0 }, { "a", 1 }, { "b", 2 }, { "x", 3 } };
swap(move(ps["cross"]), move(xbox["x"]));
The swap statement is clearly wrong, but that explains what I want to do. After the swap statement I'd like ps to contain:
{ "triangle", 0 }
{ "x", 3 }
{ "square", 2 }
{ "circle", 3 }
And xbox to contain:
{ "y", 0 }
{ "a", 1 }
{ "b", 2 }
{ "cross", 1 }
I expect there is a good way to do this with C++11's move syntax, but if possible I'd like an answer that also describes how to accomplish this on C++03.
map is implemented as an ordered tree.
You cannot simply replace a key with a new key as it might have to be placed on a different location in the tree. Consequently, you cannot swap.
Delete an re-insert the k-v pairs manually.
(As a sidenote: you haven't even told us what happens with the values...)
This question already has answers here:
Do jagged arrays exist in C/C++?
(12 answers)
Closed 8 years ago.
Is there a way to initialize two dimensional array with different size of columns in c++?
I try to make console card game.
I have done something like this while ago.
static string const group[7][];
string const Cards::group = {
{ "AA", "KK", "AKs" },
{ "QQ", "JJ", "AK", "AJs", "KQs", "AQs" },
{ "TT", "AQ", "ATs", "KJs", "QJs", "JTs" },
{ "99", "88", "AJ", "AT", "KQ", "KTs", "QTs", "J9s" , "T9s" , "98s" },
{ "77", "66", "A9s", "A5s", "A4s", "A3s", "A2s", "K9s", "KJ", "KT", "QJ", "QT", "Q9s", "JT", "QJ", "T8s", "97s", "87s", "76s", "65s"},
{ "55", "44", "33", "22", "K9", "J9", "86s"},
{ "T9", "98", "85s"}
};
It doesn't work.
It would be great if an array would be additionally static and constant but it isn't necessary. The most important thing is to make code works.
I would be grateful for any kind of help.
Arrays in C++ are not truly dynamic; they cannot be extended nor reduced in size. Moreover, the dimensions of static arrays have to be known at their declaration. Dynamically-allocated arrays can be used by declaring group as a string** and later initializing it with the appropriately-sized memory. You can also use a 2-dimensional vector which is fundamentally equivalent but preferred because it is cleaner because we can leverage its memory management:
static std::vector<std::vector<std::string>> const group;
std::vector<std::vector<std::string>> Cards::group = {
{ "AA", "KK", "AKs" },
{ "QQ", "JJ", "AK", "AJs", "KQs", "AQs" },
{ "TT", "AQ", "ATs", "KJs", "QJs", "JTs" },
{ "99", "88", "AJ", "AT", "KQ", "KTs", "QTs", "J9s" , "T9s" , "98s" },
{ "77", "66", "A9s", "A5s", "A4s", "A3s", "A2s", "K9s", "KJ", "KT", "QJ", "QT", "Q9s", "JT", "QJ", "T8s", "97s", "87s", "76s", "65s"},
{ "55", "44", "33", "22", "K9", "J9", "86s"},
{ "T9", "98", "85s"}
};
You can't use:
string group[7][] =
However, you can use:
std::vector<std::string> group[] =
Here's a working program.
#include <iostream>
#include <string>
#include <vector>
std::vector<std::string> group[] =
{
{ "AA", "KK", "AKs" },
{ "QQ", "JJ", "AK", "AJs", "KQs", "AQs" },
{ "TT", "AQ", "ATs", "KJs", "QJs", "JTs" },
{ "99", "88", "AJ", "AT", "KQ", "KTs", "QTs", "J9s" , "T9s" , "98s" },
{ "77", "66", "A9s", "A5s", "A4s", "A3s", "A2s", "K9s", "KJ", "KT", "QJ", "QT", "Q9s", "JT", "QJ", "T8s", "97s", "87s", "76s", "65s"},
{ "55", "44", "33", "22", "K9", "J9", "86s"},
{ "T9", "98", "85s"}
};
int main()
{
for ( auto it1 : group )
{
for ( auto it2 : it1 )
{
std::cout << it2 << " ";
}
std::cout << std::endl;
}
}
You cannot do
string group[7][];
Instead, you can only do
string group[][7];
for multidimensional C-style arrays.
If you truly need multidimensional array with different sizes in the last dimension, you can use std::vector> with STL.