简体   繁体   中英

Using Array[Boolean] in Scala to find out progress of foreach

I have a class in Scala that has a method to perform a bunch of calculations sequentially using foreach on a list which is provided in the constructor. The class has a field val progress: Array[Boolean] = list.map(_ => false).toArray . Some of these calculations can take a long time so at the end of each one I set the appropriate index in progress to true . Then I can get progress to determine where I am in the calculations from outside the class.

This does not seem like the best approach in Scala (because I'm using a mutable data structure) so any advice to improve it would be much appreciated.

Well, it depends on what you want to do with that information. If you are interested in specific events (eg, 50% done or something like that), you could pass a listener into your foreach method and ask to be notified. But if you really need to inquire about the current state at any time, then ... well, if you need to know the state, then you have to keep the state, there is no way around that :)

Array of booleans seems to be an overkill (you could just keep the current index instead), but you mentioned that you were planning to keep se additional info around as well, so, it looks reasonable.

I don't think your approach is bad. The alternative is to use a var progress: List[Boolean] as an immutable data structure and have a long list of immutable lists pointed at by that variable. You don't really gain anything, you lose the ability to reserve the exact memory you will need in a single step and memory allocation is going to make this slower.

There is a reason why mutable data structures exist and that is because they are incredibly useful and very needed, same as why you can still define var instead of val , the important piece is not that one is "bad" and the other "good", it is a matter of knowing when you can use val and sacrifice mutability in exchange for security. In your example you just can't.

Side note: Instead of using

val progress: Array[Boolean] = list.map(_ => false).toArray

This is much clearer and faster IMHO:

val progress = Array.fill(list.size)(false)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM