When to use "map()" or "toList()" methods?

Asked

Viewed 1,183 times

0

In the example below, the two methods basically do the same job, go through the list of objects getting each item from the list.

A difference is noted in the iteration using map(), in the last occurrence returns null.

Is there any advantage or recommendation for using each of these methods? And why the last iteration with map returns null?

class Produto {
  String nome;
  double quantidade;
}

main() {
  var produtos = List<Produto>();
  var p = Produto();
  p.nome = 'Frango';
  p.quantidade = 2.5;
  produtos.add(p);
  p = Produto();
  p.nome = 'Telha';
  p.quantidade = 1.5;
  produtos.add(p);

  var n = produtos.map((Produto p) {
    print(p);
  });  
  print(n.toList());

  produtos.forEach((p) => print(p));

}
Resultado map
    Instance of 'Produto'
    Instance of 'Produto'
    [null, null]
____________
Resultado toList()
    Instance of 'Produto'
    Instance of 'Produto'
  • 5

    The method map will turn something into something else. In this case, you are mapping the products from a list into nothing, printing halfway (since the return of print is void and you do not specify return)

  • It doesn’t help that we don’t have class definition Produto. It can be easy to create but it helps if we have it, the link posted has nothing to do with it. It seems that the question has a solution looking for a problem, IE, saw such a map() And now you want to use it, it’s not usually good. Also because you’re going to abuse it by learning like this. The map alone is good for nothing. You know C#, right? LINQ, right? The map() is the Select() of LINQ, it alone serves for something useful? It even serves, but almost always a mistake to use it. LINQ does not have a forEach() You know why? Dart has, you know why?

  • @Maniero added, had forgotten to add.

  • That’s the example I saw children: widget.products.map((Product product) {&#xA; return ShoppingListItem(&#xA; product: product,&#xA; inCart: _shoppingCart.contains(product),&#xA; onCartChanged: _handleCartChanged,&#xA; );&#xA; }).toList(), I was in doubt why not foreach()?

1 answer

2


I will try to answer the question in a general way and indicating what is most important, even if it does not give a specific solution to the problem, after all the resource is being used in a wrong way and the question has no information of what would be the way it would like to do, because it seems that learned that there is the mechanism (map()) and now he wants to apply it to some problem he doesn’t know what it is. In the middle of what I was writing came a comment showing that the original problem was another.

For the AP (which I know you’ve asked about C#) and some people I’ll compare the map() with a Select() LINQ, that is, it selects/maps an object taking data from another object. Taking data like this helps little, it is expected to at least do some manipulation operation of the members of the object when it maps to another object.

I don’t know Dart in depth, but I think it’s worth the same as has already said several times about the abuse of ToList() in LINQ. People use it more than they should, He is a materializer of the created list, because the previous queries do not generate a list, only generate the algorithm that will produce a way to access manipulated data. If Dart didn’t operate that way then it would always generate objects directly and that would be very inefficient to the point that I would say to throw this thing away on time.

It’s quite simple to use the toList(), Do you need a list now? Use it if you don’t need to. People create lists without need, often because it just follows the cake recipe. If you only need to access manipulated data that came from another data collection, you cannot create a list. I believe that this comes from the same mistake that makes people create variables without need, they don’t understand what they’re doing there and they think that if you don’t create the variable something will go wrong, she thinks you need to have a name indicating that you have an object. So the person thinks that to access the manipulated data has to create a list. Just create a list if what you want now is exactly a list, no more, no less.

I even question the existence of forEach() in the language. Do you know why you have this? Why language does not have an imperative abstract construction that traverses a data collection, or you use a for rough, or use that method. His problem is that it encourages people to use the functional way in an imperative language, and some constructions can be confusing for those who are not used to the functional way. Variable scope can be a problem, just as deviating execution is not possible equal to the complicated imperative way certain situations. There’s a reason LINQ doesn’t have ForEach(), he forms clever.

So this code makes sense (it gets the total values of the stock, note that I have not created any list, I just took the data from the existing object list):

import 'dart:io';

class Produto {
    String nome;
    double quantidade;
    double valor;
}

main() {
    var produtos = List<Produto>();
    var p = Produto();
    p.nome = 'Frango';
    p.quantidade = 2.5;
    p.valor = 10.0;
    produtos.add(p);
    p = Produto();
    p.nome = 'Telha';
    p.quantidade = 1.5;
    p.valor = 20.0;
    produtos.add(p);
    var totais = produtos.map((Produto p) => p.valor * p.quantidade);  
    totais.forEach((p) => print(p));
}

If Dart is efficient it has almost the same cost (but not the same because it has the cost of abstraction, it just won’t change the algorithm complexity) to make this code:

import 'dart:io';

class Produto {
    String nome;
    double quantidade;
    double valor;
}

main() {
    var produtos = List<Produto>();
    var p = Produto();
    p.nome = 'Frango';
    p.quantidade = 2.5;
    p.valor = 10.0;
    produtos.add(p);
    p = Produto();
    p.nome = 'Telha';
    p.quantidade = 1.5;
    p.valor = 20.0;
    produtos.add(p);
    for (var i = 0; i < produtos.length; i++) print(produtos[i].valor * produtos[i].quantidade);
}

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

I always have to talk about the use of double in monetary value because someone will read this and think it is right to use it. I can’t help but quote the builder because one might think this example is good (it is simplified only to use the mechanism, in that context it is acceptable to do so).

  • In the pub dev. has a package for decimal. I didn’t go deep enough to know what his internal implementation was like, but he pointed out to me BigDecimal of Java. Therefore, arbitrary point and arbitrary length.

  • Yeah, it looks like the same Gambiarra, it’s hard to like something that comes from Google. Dart has already given signs that there is much anyway, born another day and already tired.

  • About Dart’s "cleverness": from what I read, it’s the same behavior as Stream uses in Java 8 or several comprehension Python, only runs at the time you need it, not preloading anything.

  • Could only, otherwise, that’s what I said, throw it away.

  • My impression or called the BigDecimal of gambiarra Java? Or the existence of easy-to-publish NPM-Hell-style gambiarra packages?

  • Both :D But look at the decimal of C# and you’ll see how much better it is, although for me it’s kind of defective too :)

  • I only know the decimal SQL-Server and still barely. I believe to be equivalent to C#. If it is, it is the good old fixed point, with defined housing. It has advantages and disadvantages, but mathematically I find the arbitrary point model of varied housing more elegant, even recognizing that cases business of necessary application are scarce.

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.