reverse foreach

This forum is meant for questions and discussions about the X# language and tools
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

reverse foreach

Post by wriedmann »

Hi Robert,

the second one does not work:

Code: Select all

'Dictionary<string, int>' does not contain a definition for 'ToList' and no extension method 'ToList' accepting a first argument of type 'Dictionary<string, int>' could be found 
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

reverse foreach

Post by wriedmann »

Hi Phil,

the LinQ code does not work either:

Code: Select all

var oItems := oDict:Where( {|Item| Item:Value == nValue } )
foreach var oItem in oItems
  oDict:Remove( oItem:Key )
next
gives a runtime error because the enumeration was changed and operations cannot be executed anymore (translated from my German error message).

Wolfgang

P.S. sometimes I have the bad feeling that I'm simply not intelligent enough for all these new things
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
Chris
Posts: 4906
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

reverse foreach

Post by Chris »

Hi Wolfgang,

That's because ToList() is an extension method, defined in the System.Linq.Enumerable class of System.Core.dll. For this reason, you must make sure you have a reference to System.Core and also include a USING System.Linq in your prg file.

Chris
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

reverse foreach

Post by wriedmann »

Hi Robert,

I'm very sorry, the second sample works:

Code: Select all

foreach var oItem in oDict:ToList()
  if oItem:Value == nValue
    oDict:Remove( oItem:Key )
  endif
next
after adding System.Core and System.Linq to the references and adding a few using statements.

Sorry again!

Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
Phil Hepburn
Posts: 743
Joined: Sun Sep 11, 2016 2:16 pm

reverse foreach

Post by Phil Hepburn »

See Wolfgang,

We don't need to be clever, or intelligent - what we all need is the will to keep going ;-0)

Persevere, that is the clue ! keep on trying !!

Yesterday, and a couple of days previous to that, I had some bad 'give up' moments believe me ;-0((

Now things are working again, and life is sweet.

At least you always know that you will get good support and help from your xBase friends and colleagues. I would know nothing without their support over the years.

Thanks to all of you.

Now then ... Good Luck,
and have a nice weekend.
Seasonal greetings to one and all.
Phil.
 
User avatar
Phil Hepburn
Posts: 743
Joined: Sun Sep 11, 2016 2:16 pm

reverse foreach

Post by Phil Hepburn »

Hi guys,

Surely we can leave out the removal stuff altogether ?

After my Tea (hot meal) I will try some code similar to this below :-

var oRequiredItems := oDict:Where( {|Item| Item:Value !== nValue } )

oDict := oRequiredItems

Above we select the items we need, not the ones we don't. Since we already have our new collection then all we need do is a new assignment.

Or have I missed something ?

Best regards to all,
Phil.
NickFriend
Posts: 248
Joined: Fri Oct 14, 2016 7:09 am

reverse foreach

Post by NickFriend »

I don't know why I bothered doing this, but anyway....

Dictionary with 1 million items, every other one is removed.

Method 1 = 00:00:00.1022951 (Wolfgang's original)
Method 2 = 00:00:00.0773887 (Robert's second)
Method 3 = 00:00:00.1158190 (mine)

In other words it doesn't make the slightest difference to speed (we're talking a million items here) which technique you use.

Your choice, 9 lines of code or 1.

Nick
Frank Maraite
Posts: 178
Joined: Sat Dec 05, 2015 10:44 am
Location: Germany

reverse foreach

Post by Frank Maraite »

Wolfgang, Nick, Phil, Chris and Robert,

thanks for this nice session! Learned a lot.

BTW: MSDN says, that Add() is an O(1) and remove is a nearly O(1) operation. This may be the reason for no time differences.

Frank
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

reverse foreach

Post by wriedmann »

Hi all,

my part of this thread was very modest...

But for Nick: unfortunately I'm not able to move your code to X#, and the MS documentation says that there is not ToDictionary() method without any parameters - the X# compiler says the same thing.
I have tried this code:

Code: Select all

oDict := oDict:Where( {|Item| Item:Value != nValue } ):ToDictionary()
As I understand, the code should be

Code: Select all

oDict := oDict:ToDictionary( {|Item| Item:Value != nValue } )
but it gives the error

Code: Select all

error XS0029: Cannot implicitly convert type 'System.Collections.Generic.Dictionary<logic, System.Collections.Generic.KeyValuePair<string, int>>' to 'System.Collections.Generic.Dictionary<string, int>'
Will keep trying....

Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Frank Maraite
Posts: 178
Joined: Sat Dec 05, 2015 10:44 am
Location: Germany

reverse foreach

Post by Frank Maraite »

Wolfgang,

I know nothing about LINQ, but found (https://msdn.microsoft.com/de-de/librar ... .110).aspx)

ToDictionary(p => p.TrackingNumber)

so try
ToDictionary(p => p:Value)
Frank
Post Reply