根据其他列表删除列表条目 [英] Remove list entries depending on other list

查看:91
本文介绍了根据其他列表删除列表条目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,我有两个类列表,如下所示 - 两个classe都有一个共同的属性 - 使用Linq如何从艺术家列表中删除没有任何相册的项目?在SQL中我会说



从艺术家 code-sdkkeyword>其中 ArtistName不在 (选择ArtistName 来自相册)


class 艺术家
{
字符串 ArtistName { get ; set ;}
}

class 相册
{
字符串 ArtistName { get ; set ;}
String AlbumName { get ; set ;}
}

解决方案

既然你在回答Original Griff时说你无法改变设计,那么她我正如你所描述的那样使用这些课程:

  class 艺术家
{
字符串 ArtistName { get ; set ;}
}

class 专辑
{
字符串 ArtistName { get ; set ;}
字符串 AlbumName { get ; set ;}
}



假设两个列表的变量名称是:

AllAlbums AllArtists

然后,删除没有专辑的艺术家:

 HashSet的<串GT; AlbumArtistSet =  new  HashSet< string>(AllAlbums.Select(al = >  al.ArtistName)); 
var trimmedArtists = AllArtists.Where(a = > AlbumArtistSet.Contains(a.ArtistName )); // .ToList()如有必要



每个列表只能通过一次。



=================

编辑:MTH

由于数据是从JSon重新分析的,为什么不将它重新分解为原始格里夫提出的更有用的数据结构?

或者,如果你自己没有使用DB,那么为什么不设置类似的东西:

  //  仍假设与上面相同的AllAlbums和AllArtists。 
// (Albums类不应该被命名为Album,因为它代表一张专辑吗?)
Dictionary< string,List< Albums>> AlbumsByArtistName = new Dictionary< string,List< Albums>>();

// 现在填充字典列表。
foreach var al in AllAlbums)
{
string name = al.ArtistName;
列表<相册>专辑;
if (!AlbumsByArtistName.TryGetValue(name, out albums)
{
albums = new 列表<相册>();
AlbumsByArtistName.Add(名称,相册);
}
相册.Add(al);
}
// 现在修剪AllArtists列表你可以:
var trimmedArtists = AllArtists.Where(a = > AlbumsByArtistName .Contains(a.ArtistName)); // .ToList()如有必要



仍然只有一个通过每个集合,但现在您可以按艺术家名称访问专辑的子集集合。您可以为其他属性设置类似的字典,您可能需要子集访问。只需记住适当地添加和删除无处不在

此时你自己我可能注意到这看起来有点像数据库。 :-)

使用你自己的进程内(内存?)数据库,独立于数据源,可能是最好的解决方案。


要成为老实说,我不会。

我没有将ArtistName保留在两个地方,而是稍微改变了设计:

  class 艺术家
{
public String ArtistName { get ; set ; }
}

class 专辑
{
public 艺术家艺术家{获取; set ; }
public 字符串 AlbumName { get ; set ; }
}



这更像是你在DB中所做的事情。

然后它是微不足道的:

列表<艺术家> artists =  new  List< Artist>(); 
艺术家joe = 艺术家(){ArtistName = Joe};
Artist mike = new 艺术家(){ArtistName = 迈克};
艺术家sally = 艺术家(){ArtistName = 莎莉};
artists.Add(joe);
artists.Add(迈克);
artists.Add(莎莉);
列表<相册> albums = new 列表<相册>();
albums.Add( new 专辑(){Artist = mike,AlbumName = A1\" });
//
var lessArtists = artists.Except(albums.Select(a = > a.Artist).Distinct());


Hi all, I have two lists of classes as shown below - both classe have a common property - using Linq how can I remove items from the artist list that don't have any Albums ? In SQL I would say

Delete from Artist where ArtistName not in(Select ArtistName from Albums)


class Artist
{
    String ArtistName {get;set;}
}

class Albums
{
    String ArtistName {get;set;}
    String AlbumName {get;set;}
}

解决方案

Since you stated in your reply to Original Griff that you cannot change the design, here's what I'd do using the classes as you described:

class Artist
{
    String ArtistName {get;set;}
}
 
class Albums
{
    String ArtistName {get;set;}
    String AlbumName {get;set;}
}


Assuming the names of the variables of the two Lists are:
AllAlbums and AllArtists
Then, to delete the Artists for which there are no albums:

HashSet<string> AlbumArtistSet = new HashSet<string>(AllAlbums.Select(al => al.ArtistName));
var trimmedArtists = AllArtists.Where(a => AlbumArtistSet.Contains(a.ArtistName)); // .ToList() if necessary


This makes only one pass through each list.

=================
Edit: MTH
Since the data is being reparsed from JSon, why not reparse it into more useful data structures along the line of what Original Griff proposed?
Or, if you aren't using a DB yourself, then why not setup something like:

// Still assuming the same AllAlbums and AllArtists as above.
// (Shouldn't the Albums class be named Album since it represents ONE album?)
Dictionary<string, List<Albums>> AlbumsByArtistName = new Dictionary<string, List<Albums>>();

// Now populate the dictionary lists.
foreach (var al in AllAlbums)
{
  string name = al.ArtistName;
  List<Albums> albums;
  if (!AlbumsByArtistName.TryGetValue(name, out albums)
  {
    albums = new List<Albums>();
    AlbumsByArtistName.Add(name, albums);
  }
  albums.Add(al);
}
// Now to "trim" the AllArtists list you can:
var trimmedArtists = AllArtists.Where(a => AlbumsByArtistName.Contains(a.ArtistName)); // .ToList() if necessary


Still only one pass through each collection, but now you can access the subset collection of albums by artist name. You can setup similar dictionaries for other properties that you might want subset access. Just remember to add and delete everywhere appropriately.
At this point you've probably noticed that this is looking a bit like a DB. :-)
Using your own in-process (in-memory?) DB, independent from the data source, might be the best solution.


To be honest, I wouldn't.
Instead of keeping the ArtistName in two places, I'd change the design slightly:

class Artist
    {
    public String ArtistName { get; set; }
    }

class Album
    {
    public Artist Artist { get; set; }
    public String AlbumName { get; set; }
    }


Which would be more like what you would do in a DB.
Then it's trivial:

            List<Artist> artists = new List<Artist>();
            Artist joe = new Artist() { ArtistName = "Joe" };
            Artist mike = new Artist() { ArtistName = "Mike" };
            Artist sally = new Artist() { ArtistName = "Sally" };
            artists.Add(joe);
            artists.Add(mike);
            artists.Add(sally);
            List<Album> albums = new List<Album>();
            albums.Add(new Album() {Artist = mike, AlbumName = "A1"});
//
            var lessArtists = artists.Except(albums.Select(a => a.Artist).Distinct());


这篇关于根据其他列表删除列表条目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆