我是LINQ的新手,遇到了问题。我有一个看起来像这样的文件:
<?xml version="1.0" encoding="utf-8" ?>
<Galleries>
<Gallery ID="10C31804CEDB42693AADD760C854ABD" Title="Test1">
<Description>The first test gallery. Picture of a cat and Wilford Brimley. Can you tell the difference?</Description>
<Images>
<Image Title="t1Image1" FileName="tcats.jpg" />
<Image Title="t1Image2" FileName="twb.jpg" />
</Images>
</Gallery>
<Gallery ID="0420EC15405B488E1E0F157AC823A6" Title="Test2">
<Description>The second test gallery. A large image of Wilford Brimley and various cats. The cats will be on the right.</Description>
<Images>
<Image Title="t2Image1" FileName="wilfordbrimley.jpg" />
</Images>
</Gallery>
</Galleries>
无论如何,我知道我想要的图库的ID,但我想随机选择其中一个图像。是否有可以执行此操作的LINQ语句?
答案 0 :(得分:3)
您可以通过Random.Next()在图库中订购图像,然后选择第一个元素。
我对linq2xml不太了解,但这就是我想出的
static void Main(string[] args)
{
Random rnd = new Random();
XDocument galleries = XDocument.Load(@"C:\Users\John Boker\Documents\Visual Studio 2008\Projects\ConsoleApplication1\ConsoleApplication1\Galleries.xml");
var image = (from g in galleries.Descendants("Gallery")
where g.Attribute("ID").Value == "10C31804CEDB42693AADD760C854ABD"
select g.Descendants("Images").Descendants("Image").OrderBy(r=>rnd.Next()).First()).First();
Console.WriteLine(image);
Console.ReadLine();
}
我确信选择可以做很多不同的事情,但这就是我用它来处理random.next的事情。
答案 1 :(得分:1)
以下是一些依赖于计算Image
个节点数量的解决方案;效率不是很高,但我认为你不能做得更好,因为许多Linq集合类型都被公开为IEnumerable
。
XElement GetRandomImage(XElement images)
{
Random rng = new Random();
int numberOfImages = images.Elements("Image").Count();
return images.Elements("Image").Skip(rng.Next(0, numberOfImages)).FirstOrDefault();
}
XElement GetRandomImage(XElement images)
{
Random rng = new Random();
IList<XElement> images = images.Elements("Image").ToList();
return images.Count == 0 :
null ?
images[rng.Next(0, images.Count - 1)];
}
答案 2 :(得分:0)
我不建议使用所选答案,因为它使用的排序为O(n log n)
,其中n
是所选图库中的图像数量。您可以在O(1)
时间内从列表中选择随机项。因此,我会使用以下内容:
using(StreamReader sr = new StreamReader(File.Open(path, FileMode.Open))) {
XDocument galleries = XDocument.Load(sr);
string id = "10C31804CEDB42693AADD760C854ABD";
var query = (from gallery in galleries.Descendants("Galleries")
.Descendants("Gallery")
where (string)gallery.Attribute("ID") == id
select gallery.Descendants("Images")
.Descendants("Image")
).SingleOrDefault();
Random rg = new Random();
var image = query.ToList().RandomItem(rg);
Console.WriteLine(image.Attribute("Title"));
}
我在这里使用:
static class ListExtensions {
public static T RandomItem<T>(this List<T> list, Random rg) {
if(list == null) {
throw new ArgumentNullException("list");
}
if(rg == null) {
throw new ArgumentNullException("rg");
}
int index = rg.Next(list.Count);
return list[index];
}
}