私は今しばらくLINQを使用していますが、ユニークアイテムに関して何かに行き詰まっているようです。次のリストがあります。
List<Stock> stock = new List<Stock>();
これには次のプロパティがあります:文字列ID、文字列タイプ、文字列説明、例:
public class Stock
{
public string ID { get; set; }
public string Type { get; set; }
public string Description { get; set; }
}
在庫のアイテムをタイプ別にグループ化し、これを新しい在庫リストとして返すLINQクエリが必要です(元の在庫リストと同じタイプである必要があります)。
データの例:
ID Type Description
----------------------------------------------
1 Kitchen Appliance Dishwasher
2 Living Room Television
3 Kitchen Appliance Washing Machine
4 Kitchen Appliance Fridge
...
私のLinqクエリは、例としてすべてのキッチンアプライアンスを返すことができるようにしたいと考えています。
したがって、これを「タイプ」としてクエリに渡し、この例のリストからアイテム1、3、4を返します。
返されるこのリストもList<Stock>
タイプである必要があります。
基本的に、SQL Distinctクエリのような種類ごとの一意の項目のリストが必要です。これをLINQで実現するにはどうすればよいですか?
代替ソリューションは問題ありませんが、Silverlight/C#クライアントコードのみである必要があります。
もう1つの明確化は、パラメーター「キッチンアプライアンス」も提供せず、ユニークなものだけが必要な場合があることです。たとえば、キッチンアプライアンスとリビングルームは、そのタイプの数に関係なく、カテゴリのようなものに1回だけ返されます。がある。
GroupBy
と ToDictionary
を使用して、Type
プロパティをキーとするList<Stock>
値の辞書を作成します。
var appliancesByType = stock
.GroupBy(item => item.Type)
.ToDictionary(grp => grp.Key, grp => grp.ToList());
そうすれば、特定のタイプのリストだけでなく、タイプ自体にも非常に簡単にアクセスできます。
// List of unique type names only
List<string> stockTypes = appliancesByType.Keys.ToList();
// Or: list of one stock item per type
List<Stock> exampleStocks = appliancesByType
.Select(kvp => kvp.Value[0])
.ToList();
// List of stock items for a given type
List<Stock> kitchenAppliances = appliancesByType["Kitchen Appliance"];
このアプローチは、私が見ているように、実際にすべてのニーズを処理します。ただし、他のいくつかのオプションについては、以下を参照してください。
常に Where
を使用して必要なタイプのアイテムを取得し、次に ToList
を使用してこれらのアイテムを新しいList<Stock>
:
List<Stock> kitchenAppliances = stock
.Where(item => item.Type == "Kitchen Appliance")
.ToList();
この最後の部分への応答:
もう1つの明確化は、パラメーター「キッチンアプライアンス」も提供せず、ユニークなものだけが必要な場合があることです。たとえば、キッチンアプライアンスとリビングルームは、そのタイプの数に関係なく、カテゴリのようなものに1回だけ返されます。がある。
ここでは、完全に異なるものを望んでいるようです:基本的に Distinct
によって提供される動作。この機能については、基本的に Soontsの回答 を使用できます(オプションで、IEnumerable<tKey>
ではなくIEnumerable<tSource>
を返します)、またはDistinct
を組み合わせて使用することもできます Select
を使用すると、IEqualityComparer<Stock>
を実装する必要がなくなります(以下を参照)。
あなたの明確化に応えて、これが私の推奨です:各目的に1つずつの2つの方法( 単一の責任の原則 ):
// This will return a list of all Stock objects having the specified Type
static List<Stock> GetItemsForType(string type)
{
return stock
.Where(item => item.Type == type)
.ToList();
}
// This will return a list of the names of all Type values (no duplicates)
static List<string> GetStockTypes()
{
return stock
.Select(item => item.Type)
.Distinct()
.ToList();
}
必要な単純なWhere句のように聞こえます。
_List<Stock> kitchen= stock.Where(s=>s.Type=="Kitchen Appliance")
.OrderBy(s=>s.Description).ToList();
_
厳密にソースリストに含まれるTypes
が必要な場合:
string[] typesFound = stock.Select(s=>s.Type).Distinct().ToArray();
static class EnumerableEx
{
// Selectively skip some elements from the input sequence based on their key uniqueness.
// If several elements share the same key value, skip all but the 1-st one.
public static IEnumerable<tSource> uniqueBy<tSource, tKey>( this IEnumerable<tSource> src, Func<tSource, tKey> keySelecta )
{
HashSet<tKey> res = new HashSet<tKey>();
foreach( tSource e in src )
{
tKey k = keySelecta( e );
if( res.Contains( k ) )
continue;
res.Add( k );
yield return e;
}
}
}
// Then later in the code
List<Stock> res = src.uniqueBy( elt => elt.Type ).ToList()
var kitchenAppliances = stocks.Where(stock => stock.Type == "Kitchen Appliance");
これらの線に沿って何かを実行することもできます。この場合、私はルセンの結果を取得してから、umbracoノードを匿名型にプルオフします
var datasource = (from n in SearchResults
select new
{
PageLink = uQuery.GetNode(n.Id).NiceUrl,
uQuery.GetNode(n.Id).Name,
Date = uQuery.GetNode(n.Id).GetProperty("startDate"),
IntroText = string.IsNullOrEmpty(uQuery.GetNode(n.Id).GetProperty("introText").Value) ? string.Empty : uQuery.GetNode(n.Id).GetProperty("introText").Value,
Image = ImageCheck(uQuery.GetNode(n.Id).GetProperty("smallImage").Value)
}).Distinct().ToList();
私はおそらく質問を理解していませんが、これは非常に単純なLinqクエリのように聞こえます。
List<Stock> stock = new List<Stock>();
... populate your list as per your example
List<Stock> kitchenAppliances =
(from obj in stock
where obj.Type == "Kitchen Appliance"
select obj).ToList();
または、拡張メソッドの構文を使用する場合:
List<Stock> kitchenAppliances =
stock.Where(obj => obj.Type == "Kitchen Appliance").ToList();
私が理解していないのは、この文脈での明確でユニークなあなたの使用法です。オブジェクトは既に一意であり、「すべての台所用品をください」という基本的なクエリが必要なようです。