Linq or dictionary

  • Thread starter Thread starter Ethan Strauss
  • Start date Start date
E

Ethan Strauss

Hi,
I am pretty new to Linq and I am not quite sure when it is best to use it
and when other methods might be preferable.
For example, I need to create a list of Sample objects which I then access
by the SampleName property of each sample.
The way I have generally done this would be with a Dictionary<string,
Sample>, but instead I can use a List<Sample> and access using linq. I don't
know which would be preferable. Any thoughts?
I have example code below.
Thanks!
Ethan

With Dictionary
Dictionary<string, Sample> samples = new Dictionary<string, Sample>();
while (reader.Peek() > 0)
{
string[] line = reader.ReadLine().Split('\t');
if (samples.ContainsKey(line[1]))
{
samples[line[1]].AddDyeChannel(line);
}
else
{
samples.Add(line[1], new Sample(line));
}
}

With List and Linq
List<Sample> samples = new List<Sample>();
while (reader.Peek() > 0)
{
string[] line = reader.ReadLine().Split('\t');
var thisSample = from samp in samples
where samp.SampleName == line[1]
select samp;
switch (samples.Count)
{
case 0:
{
samples.Add(new Sample(line));

break;
}

case 1:
{
samples.First().AddDyeChannel(line);
break;
}
default:
{
throw new
ArgumentException(string.Format("Sample {0} was in the list more than once.",
line[1]));
}
}
}
 
I messed up the linq example.
I think the concept was probably still clear, but here is the way it should be
 
Ethan said:
Hi,
I am pretty new to Linq and I am not quite sure when it is best to use it
and when other methods might be preferable.

Generally speaking, use LINQ when it allows the code to express your
_intent_ more clearly. Especially if the code becomes simpler as a
result (which it often can, if LINQ is a better expression of intent).

A main goal of LINQ is to allow the code to move away from a literal
expression of the _mechanism_ and toward a more descriptive, intentional
expression.
For example, I need to create a list of Sample objects which I then access
by the SampleName property of each sample.
The way I have generally done this would be with a Dictionary<string,
Sample>, but instead I can use a List<Sample> and access using linq. I don't
know which would be preferable. Any thoughts?

I would say that just because LINQ exists, that doesn't negate the
existing rules of thumb for choice of data structure. In particular, in
your example you are specifically mapping a key to a specific instance,
which is exactly what the Dictionary<TKey, TValue> type does.

On the other hand, the LINQ implementation you've shown doesn't really
express the actual operation you're interested in very well. And on top
of that, it's WAY more expensive computationally than using
Dictionary<TKey, TValue>.

I'd say that for this specific example at least, LINQ is a clear loser,
at least used the way you've written it.

It's hard to know with such a minimal code example, but it's possible
that if you extended your LINQ expression to use the "group" keyword, so
that LINQ does all the work of maintaining the dictionary, that actually
would express the intent better. For example:

First, encapsulate the i/o as an IEnumerable, so that it fits into LINQ:

IEnumerable<string[]> ReadLines()
{
while (reader.Peek() > 0)
{
yield return reader.ReadLine().Split('\t');
}
}

Then elsewhere:

var result =
from line in ReadLines()
group line by line[1];

foreach (IEnumerable<string[]> grouped in result)
{
Sample sample = null;

foreach (string[] line in grouped)
{
if (sample == null)
{
sample = new Sample(line);
}
else
{
sample.AddDyeChannel(line);
}
}

// save the Sample instance somewhere?
}

The above example becomes even more expressive if you can allocate an
empty Sample instance:

var result =
from line in ReadLines()
group line by line[1];

foreach (IEnumerable<string[]> grouped in result)
{
Sample sample = new Sample();

foreach (string[] line in grouped)
{
sample.AddDyeChannel(line);
}

// save the Sample instance somewhere?
}

In other words, the above does this:

– create a query from the data source, grouping each line according
to the key
– enumerate all the groups:
– for each group, enumerate all the dye channels, adding them to
the Sample current instance

As you can see from the above, using LINQ works best if your data
structures and code are designed with LINQ in mind. Mapping it after
the fact results in less elegant expressions and usages.

The Dictionary<string, Sample> version is fine. It works, it's
efficient, and experienced programmers will recognize the pattern. But
it's much better at expressing the actual mechanism being used, than it
is the end goal the code has. IMHO, the LINQ version does the latter
better. But of course, doing it properly requires more than just
throwing some LINQ at the problem. You have to throw the _right_ LINQ
at the problem, and that may involve some up-front work so that the
problem is represented in a way that suits LINQ better.

On that last point, note that I didn't _have_ to create an iterator
method to do that. I could have started with a List<string[]> populated
by a loop, and then executed the query against the List<string[]>
instance. But that would have been inefficient, because it would
require the intermediate data structure. Using an iterator method, the
original input is filtered directly into LINQ, allowing it to do all of
the mechanical work.

Hope that helps!

Pete
 
Hello,

As show by the code you posted in this case LINQ looks a bit overkill to me.
The more complex what you are doing is, the better it is (for example
grouping files by estension and computing the total of the size would be
clearly expressed using a LINQ query).

If you just need to access a dictionary it seems really overkill

--
Patrice


"Ethan Strauss" <[email protected]> a écrit dans le
message de groupe de discussion :
(e-mail address removed)...
 
Linq is costlier interms of data extraction ..

So recommend you to use traditional methods.

Angel J. Hernandez M. said:
Hey mate,

I think you could create an extension class for the Dictionary, and add
that LINQ processing capability to it

Regards,


--
Angel J. Hernández M
MCP,MCAD,MCSD,MCDBA
Microsoft MVP

http://twitter.com/angeljesus14
http://msmvps.com/blogs/angelhernandez


Ethan Strauss said:
Hi,
I am pretty new to Linq and I am not quite sure when it is best to use
it
and when other methods might be preferable.
For example, I need to create a list of Sample objects which I then
access
by the SampleName property of each sample.
The way I have generally done this would be with a Dictionary<string,
Sample>, but instead I can use a List<Sample> and access using linq. I
don't
know which would be preferable. Any thoughts?
I have example code below.
Thanks!
Ethan

With Dictionary
Dictionary<string, Sample> samples = new Dictionary<string, Sample>();
while (reader.Peek() > 0)
{
string[] line = reader.ReadLine().Split('\t');
if (samples.ContainsKey(line[1]))
{
samples[line[1]].AddDyeChannel(line);
}
else
{
samples.Add(line[1], new Sample(line));
}
}

With List and Linq
List<Sample> samples = new List<Sample>();
while (reader.Peek() > 0)
{
string[] line = reader.ReadLine().Split('\t');
var thisSample = from samp in samples
where samp.SampleName == line[1]
select samp;
switch (samples.Count)
{
case 0:
{
samples.Add(new Sample(line));

break;
}

case 1:
{
samples.First().AddDyeChannel(line);
break;
}
default:
{
throw new
ArgumentException(string.Format("Sample {0} was in the list more than
once.",
line[1]));
}
}
}
 
Back
Top