チーズパン
チーズパン

Reputation: 2778

How exactly to use array.where?

I'm not sure if I got the right idea of how array.where() works. I've got an array filled with Spectrum.cs objects. each spectrum contains a filename-property.

mySpectrum.filename; //String

Now I have a stringvalue that I want to compare with each object in the array to find out, whether it has the same filename. As I got it it should work like this:

Spectrum bgSpec = new Spectrum(); //Has a filename
Spectrum[] currentSpectra;  //Array filled with Spectra

//Somehow this doesn't seem to work. Propably due to the returnvalue for where() which seems //to be IEnumerable.
Spectrum tempSpectrum = currentSpectra.Where<Spectrum>(c => c.filename == bgSpec);

I propably got everything wrong and would be very grateful if somebody could point out what it is or how to do it right.

Thanks in advance, BC++

Upvotes: 5

Views: 35103

Answers (4)

Kishore Kumar
Kishore Kumar

Reputation: 12874

Use Single or SingleOrDefault in your LINQ instead of Where

var tempSpectrum = currentSpectra.SingleOrDefault(c => c.filename == bgSpec.filename); 

Upvotes: 1

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236268

As John said, Single is appropriate here. If you are have several spectrum objects, which could match condition, then you should use list of spectrum objects instead. Also you should compare filename properties

IEnumerable<Spectrum> tempSpectrums = currentSpectra.Where(c => c.filename == bgSpec.filename);
Spectrum tempSpectrum = currentSpectra.SingleOrDefault(c => c.filename == bgSpec.filename);

Also keep in mind, that you don't need to specify generic type for such methods like Where, Single, SingleOrDefault - type will be inferred by compiler from collection type.

Upvotes: 2

Jon
Jon

Reputation: 437524

Where narrows down the input sequence to a subset. That's not exactly what you want here, which is probably more like

var tempSpectrum = currentSpectra
                   .SingleOrDefault(c => c.filename == bgSpec.Filename);

SingleOrDefault will return either the Spectrum instance your are looking for or (assuming Spectrum is a reference type) null if no such spectrum exists. It will also throw an exception if there are multiple spectra that match the search parameter.

If this is not exactly what you want, look also into Single and First/FirstOrDefault.

There are also non-LINQ alternatives to most of these: Array.Find and several more static Array.FindX methods.

Upvotes: 4

Jon Skeet
Jon Skeet

Reputation: 1502016

It looks like you're looking for a single value meeting that criterion. So maybe use Single:

var tempSpectrum = currentSpectra.Single(c => c.filename == bgSpec.filename);

Other options:

The OrDefault versions will return null if there's no matching element. The difference between First, Single and Last is in terms of the result for multiple matches: Single will throw an exception, whereas First or Last will take the first or last match respectively.

Which of these is most appropriate will depend on exactly what you want to do.

Upvotes: 11

Related Questions