How to get the biggest value in list of object?
I want compare the case number
print(_abcBloc.vpStream.value);
_abcBloc.vpStream.value
.sort((a, b) => a['caseNumber'].compareTo(b['caseNumber']));
print(_abcBloc.vpStream.value.last['caseNumber']);
Error
[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: type '(dynamic, dynamic) => dynamic' is not a subtype of type '(ABC, ABC) => int' of 'compare'
This is _abcBloc.vpStream.value output :
[ABC(priority: null,caseNumber: 1,....), ABC(priority: null, caseNumber:2,...)]
I also want to add that you don't need to sort the map if you just want to find the biggest value. You can instead use the reduce method to iterate through each value in the list and determine which value you want to keep in the iteration:
void main() {
final listOfMaps = [
{'caseNumber': 1},
{'caseNumber': 3},
{'caseNumber': 2}
];
final mapWithBiggestCaseNumber =
listOfMaps.reduce((a, b) => a['caseNumber'] > b['caseNumber'] ? a : b);
print(mapWithBiggestCaseNumber); // {caseNumber: 3}
}
you could use math library and reduce to check for the max value
import 'dart:math';
num biggest = _abcBloc.vpStream.value
.map((abc) => abc.caseNumber).reduce(max);
As mentioned in the comments, simply write the type of the parameters in the lambda as (ABC a, ABC b) to tell the Dart compiler about the types of the lambda. Without the types, the Dart compiler assumes they are dynamic, which raises the issue you are facing.
Edit: as the other answers noted, you shouldn't use a sort call as it is less effecient (O(nlogn)) than it needs to be (O(n)). Thus, while what I said works, it would be better to use a reduce call.
Related
I need to concatenate multiple instances of boost::iterator_range.
My initial idea was to use boost::join, but it looks like it takes only two ranges as parameters.
On another question I found that the most voted answer was "well, just call join again", but that is not working in my case.
I realized the reason might be that I do not know at compile time the exact number of ranges I am going to join, resulting in boost::join not knowing its return type.
To make it more clear, I need to use it in a ranged for loop, such as the following:
SomeRangeType result;
for ( const auto& a_range : some_list_of_ranges )
{
result = boost::join( result, a_range );
}
return result;
Does another join-like operation like the one I need exist in boost?
range-v3 has concat and join views, it seems you want join view here:
std::vector<std::vector<int>> v{{1, 2, 3}, {4}, {5, 6}};
for (auto e : v | ranges::view::join) {
std::cout << e << " "; // 1 2 3 4 5 6
}
Demo
C++ does not have run-time dynamic templates, so the idea does not work with boost::range.
We can have 2 ranges r1 and r2 with types R1 and R2 and when we join those then we get result (lets name it r12) of type boost::joined_range<R1,R2>.
We can have third range (say r3 of type R3) and joining it with r12 we would get result of type boost::joined_range<boost::joined_range<R1,R2>,R3>.
The ranges r1, r2, r3 etc. can be passed to variadic template function as arguments and from list of arguments we can make compiler to figure what is the resulting type. Same is when we have the ranges in fixed length collection (like std::tuple or std::array), we can make compiler to figure what is the resulting type of joining those.
However if we don't have fixed amount of ranges but run-time dynamic amount (like from std::vector) then we don't know what will be the type of joining these and also compiler can't figure it out compile time. Every type however must be known compile time in C++.
So you have either to find a way to fix the amount of ranges you join compile time or you have to use that dynamic, not joined collection (like vector) of ranges as your data type or you have to use some third thing like range-v3.
I need to write a method that will return the contents of a particular row (index of it is inputted as method parameter). I have to use recursion and no loops.
So far I have attempted this uncompleted code (and I have no idea how to continue it):
class Sudoku(val grid: List[List[Int]]) {
def r(r: Int): Set[Int] = {
if (grid.isEmpty) Set()
else
}
}
I also do not know how Set works. Any help would be really appreciated. PS: I am not asking for complete code, an algorithm explanation would be more than enough!
This is the answer to the literal interpretation of the question:
class Sudoku(val grid: List[List[Int]]) {
def row(n: Int): List[Int] =
if (grid.size > n) grid(n) else Nil
}
The apply method on List, here applied on the value grid, which can be written either grid apply n, or simply grid(n) returns the n'th element of the list. If that element does not exist (e.g. grid(1000000)), it throws an exception, therefore we check the size of the list first.
I have no idea why you should return a Set, but you could simple call .toSet on the result. A Set is a collection with distinct elements (each element only occurs once) with no guarantee of ordering.
I also don't know why you would need recursion for this, so I reckon the question is part of a larger problem.
I wanted to know if there was a way to find an int in a double type map container. For instance in the following example
std::map<double,double> mt;
mt[2.33] =3.45;
if(mt.find(2)!=mt.end()) //How to do a search for an int instead of a map
{
//Found
}
I wanted to know if there was a way to tell the map to search for an int instead of a double. Since the map would search for a double by default.
One way you can do this is to use lower_bound/upper_bound member functions to get a range of values around your integer, and then check this range manually.
Other way is to use a map with custom comparator that compares keys as integers (see std::map referernce), so you preserve initial key values and can search for integers. But you can't search for doubles then.
Anyways, the task is a bit strange, you probably should reconsider your data structures choice for your problem.
The following should work:
it = mt.lower_bound(2);
However, you need to check the item afterwards;
it->first<3;
must yield true for correct result.
if you are interested only in the integral part (or anything else, as you can use a lambda for that), you might use
auto result = find_if(begin(mt), end(mt),
[&](pair<double, double> p){return (int)(p.first) == 2)}
)
if (result != mt.end())
{
// do your stuff
}
The use case for such a kind of approach still remains unclear...
Suppose that I have an array. I want to remove all the elements within the array that have a given value. Does anyone know how to do this? The value I am trying to remove may occur more than once and the array is not necessarily sorted. I would prefer to filter the array in-place instead of creating a new array. For example, removing the value 2 from the array [1, 2, 3, 2, 4] should produce the result [1, 3, 4].
This is the best thing I could come up with:
T[] without(T)(T[] stuff, T thingToExclude) {
auto length = stuff.length;
T[] result;
foreach (thing; stuff) {
if (thing != thingToExclude) {
result ~= thing;
}
}
return result;
}
stuff = stuff.without(thingToExclude);
writeln(stuff);
This seems unnecessarily complex and inefficient. Is there a simpler way? I looked at the std.algorithm module in the standard library hoping to find something helpful but everything that looked like it would do what I wanted was problematic. Here are some examples of things I tried that didn't work:
import std.stdio, std.algorithm, std.conv;
auto stuff = [1, 2, 3, 2, 4];
auto thingToExclude = 2;
/* Works fine with a hard-coded constant but compiler throws an error when
given a value unknowable by the compiler:
variable thingToExclude cannot be read at compile time */
stuff = filter!("a != " ~ to!string(thingToExclude))(stuff);
writeln(stuff);
/* Works fine if I pass the result directly to writeln but compiler throws
an error if I try assigning it to a variable such as stuff:
cannot implicitly convert expression (filter(stuff)) of type FilterResult!(__lambda2,int[]) to int[] */
stuff = filter!((a) { return a != thingToExclude; })(stuff);
writeln(stuff);
/* Mysterious error from compiler:
template to(A...) if (!isRawStaticArray!(A)) cannot be sliced with [] */
stuff = to!int[](filter!((a) { return a != thingToExclude; })(stuff));
writeln(stuff);
So, how can I remove all occurrences of a value from an array without knowing the indexes where they appear?
std.algorithm.filter is pretty close to what you want: your second try is good.
You'll want to either assign it to a new variable or use the array() function on it.
auto stuffWithoutThing = filter!((a) { return a != thingToExclude; })(stuff);
// use stuffWithoutThing
or
stuff = array(filter!((a) { return a != thingToExclude; })(stuff));
The first one does NOT create a new array. It just provides iteration over the thing with the given thing filtered out.
The second one will allocate memory for a new array to hold the content. You must import the std.array module for it to work.
Look up function remove in http://dlang.org/phobos/std_algorithm.html. There are two strategies - stable and unstable depending on whether you want the remaining elements to keep their relative positions. Both strategies operate in place and have O(n) complexity. The unstable version does fewer writes.
if you want to remove the values you can use remove
auto stuffWithoutThing = remove!((a) { return a == thingToExclude; })(stuff);
this will not allocate a new array but work in place, note that the stuff range needs to be mutable
I have a problem creating a std::map<int, int> from a vector of pointers, called files. Each pointer points to an object with three member variables, one of which is size of type int. The key of the map would be the size and the value would be the number of objects which have the same size.
Do NOT waste your time on the second one! It is the next step in my program and I have figured it out already, I think. For initialization of the map I am using std::accumulate, because it returns a value. I am using std::tr1::shared_ptr for the pointers and a lambda expression for the predicate function. I am having problems with compilation.
Here's the code snippet:
map<int,int>* sizes = new map<int,int>();
sizes = accumulate(files.begin(), files.end(),sizes,
[&sizes](map<int,int> acc, shared_ptr<CFileType>& obj)
{
return sizes->insert(pair<int,int>(obj->getSize(),0));
});
Here's the error:
error C2664: 'std::pair<_Ty1,_Ty2> `anonymous-namespace'::::operator ()(std::map<_Kty,_Ty>,std::tr1::shared_ptr &) const' : cannot convert parameter 1 from 'std::map<_Kty,_Ty> ' to 'std::map<_Kty,_Ty>'
I am not very sure what to pass to the lambda function. I have tried with pair<int, int>, but it didn't work. Also, I must mention that this map is returned to another function, so it has to be a pointer.
Any help from you would be appreciated. Thanks!
UPDATE:
Problem solved, here is the solution:
map<int,int>* sizes = accumulate(files.begin(), files.end(), new map<int,int>(),
[](map<int,int>* acc, shared_ptr<CFileType>& obj)->map<int,int>*
{
acc->insert(pair<int,int>(obj->getSize(),0));
return acc;
});
The error message is that you have a type mismatch between the two kinds of std::maps. It looks like the error is in the code that calls the lambda, which apparently passes the wrong thing for the acc parameter. The good news is that the lambda, as posted, never actually uses the acc parameter.