Related
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);
}
});
}
Here's my settings:
{
"C_Cpp.errorSquiggles": "Enabled",
"C_Cpp.intelliSenseEngine": "Default",
"C_Cpp.intelliSenseEngineFallback": "Disabled",
"C_Cpp.clang_format_fallbackStyle": "{ BasedOnStyle: Google, IndentWidth: 4, ColumnLimit: 0}",
"workbench.sideBar.location": "right",
"files.exclude": {
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true
},
"editor.formatOnPaste": true,
"editor.formatOnType": true,
"terminal.integrated.shell.windows": "C:/msys64/usr/bin/bash.exe",
"terminal.integrated.shellArgs.windows": [ "-i" ],
"terminal.integrated.env.windows": {
"MSYSTEM": "MINGW64",
"PATH" : "/mingw64/bin:/usr/local/bin:/usr/bin:/bin:/c/Windows/System32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0/"
}
}
It correctly format braces as:
void myCode() {
}
and not:
void myCode()
{
}
but when I copy/paste, it also add a new indention, such as:
void myCode() {
}
Expecially when there are some code before this.
Why? How can i fix it?
EDIT: here's a practical example. This is the code I have:
struct Test : Module
{
enum ParamIds {
TRIGGER_PARAM,
CYCLE_PARAM,
RATE_PARAM,
RATE_FINE_PARAM,
RISE_LENGTH_PARAM,
NUM_PARAMS
};
enum InputIds
{
TRIGGER_INPUT,
TAIL_LENGTH_CV_INPUT,
NUM_INPUTS
};
enum OutputIds {
EOR_OUTPUT,
EOF_OUTPUT,
EOC_OUTPUT,
RISING_OUTPUT,
FALLING_OUTPUT,
OUT_OUTPUT,
NUM_OUTPUTS
};
};
If now within InputIds I paste a value in that empty space, that's the result:
struct Test : Module
{
enum ParamIds {
TRIGGER_PARAM,
CYCLE_PARAM,
RATE_PARAM,
RATE_FINE_PARAM,
RISE_LENGTH_PARAM,
NUM_PARAMS
};
enum InputIds {
TRIGGER_INPUT,
ASD_PARAM,
TAIL_LENGTH_CV_INPUT,
NUM_INPUTS
};
enum OutputIds {
EOR_OUTPUT,
EOF_OUTPUT,
EOC_OUTPUT,
RISING_OUTPUT,
FALLING_OUTPUT,
OUT_OUTPUT,
NUM_OUTPUTS
};
};
As you can see, it adds a tab and mess the whole code.
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
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 }
},
};
I'm trying to make use of precalculated values by outputting them to a header file and then compiling them for use.
The precalculated values are cube co ordinates mapped onto a sphere and the data structure takes the form of:
typedef float heightMapCubeFace[5][5][3];
I am defining each face seperately like so:
heightMapCubeFace face1 = {{{ -2.88675, -2.88675, -2.88675 }, { -3.38502, -3.38502, -1.44338 }, { -3.53553, -3.53553, 0 }, { -3.38502, -3.38502, 1.44338 }, { -2.88675, -2.88675, 2.88675}},
{{ -1.44338, -3.38502, -3.38502 }, { -1.69251, -4.38986, -1.69251 }, { -1.76777, -4.67707, 0 }, { -1.69251, -4.38986, 1.69251 }, { -1.44338, -3.38502, 3.38502}},
{{ 0, -3.53553, -3.53553 }, { 0, -4.67707, -1.76777 }, { 0, -5, 0 }, { 0, -4.67707, 1.76777 }, { 0, -3.53553, 3.53553}},
{{ 1.44338, -3.38502, -3.38502 }, { 1.69251, -4.38986, -1.69251 }, { 1.76777, -4.67707, 0 }, { 1.69251, -4.38986, 1.69251 }, { 1.44338, -3.38502, 3.38502}},
{{ 2.88675, -2.88675, -2.88675 }, { 3.38502, -3.38502, -1.44338 }, { 3.53553, -3.53553, 0 }, { 3.38502, -3.38502, 1.44338 }, { 2.88675, -2.88675, 2.88675}}
};
and finally:
heightMapCubeFace * heightMapSaved[6] = {&face1, &face2, &face3, &face4, &face5, &face6};
Eventually the data structue will be bigger I hav ejust set it to 5x5 to make things easier at first.
The problem I am having is when I want to get the values back, something weird is happening and as a result access violations are occuring.
As shown in the following image
As you can see the assigned value does not match that of the data structure. Instead the value for index [0][0][0][1] is given the value of index [0][0][1][0].
here
I picked up on this because an unhaddled exception is thrown at a later stage (access violation), I think it is because of this index problem but can't be certain.
I don't understand what is going on, am I dereferencing the pointer wrong?
Any help would be much appriciated, thanks.
Here is the code for that section:
for(int i = 0; i < 6; i++)
{
for(int j = 0; j < heightMapRes; j++)
{
for(int k = 0; k < heightMapRes; k++)
{
float xCoord = *(heightMapSaved[i][j][k][0]);
float yCoord = *(heightMapSaved[i][j][k][1]);
float zCoord = *(heightMapSaved[i][j][k][2]);
float newValue = myModule.GetValue( xCoord, yCoord, zCoord);
heightMap.SetValue( j, k, newValue);
}
}
}
layout is (heightMapSaved[6])[5][5][3] not (heightMapSaved[5][5][3][6])