如何编辑列表的列表元素

本文关键字:列表 列表元素 编辑 何编辑 | 更新日期: 2023-09-27 18:11:41

我有一个:

var list = new List<List<MyClass>>();

MyClass:

public class MyClass
{
  public double X { set; get; }
  public double Y { set; get; }
  public bool Unique{ set; get; }
}

现在我有一个double xdouble y,我想找到具有相同X and Y的列表元素,并将Unique字段设置为false。

我已经找到了搜索的例子,如:

var element = (from sublist in list
               from item in sublist
               where item.X == x && item.Y == y
               select item).FirstOrDefault();

但是如何编辑这个元素呢?

当然,我可以这样做:

foreach (var myClsList in list)
{
  foreach (var myCls in myClsList )
  {
    if (myCls.X == x && myCls.Y == y)
    {
      myCls.Unique= false;
    }
  }
}

但是看起来不好看

如何编辑列表的列表元素

看起来你真的想XY属性对元素进行分组,并在这些组中正确设置Unique属性。以下是一些初步的想法:

List<Element> allItems = list.SelectMany(l => l);
var groups = allItems.GroupBy(element => new { X = element.X, Y = element.Y });
foreach (var group in groups) {
    bool unique = group.Count() == 1;
    foreach (var element in group) {
        element.Unique = unique;
    }
}

似乎很不清楚是要编辑一个元素,还是要编辑符合特定条件的整个元素。

对于一个元素:

(from sublist in list
 from item in sublist
 where item.X == x && item.Y == y
 select item).First().Unique = false; //the default item will be null

这个可以工作,但是很难看。好:

var element = (from sublist in list
               from item in sublist
               where item.X == x && item.Y == y
               select item).FirstOrDefault();
element.Unique = false;

要全部更改,请使用foreach。Linq并不是针对副作用的。它应该是一个副作用构造。在你的情况下,我会这样做:

var query = list.SelectMany(sublist => sublist)
                .Where(item => item.X == x && item.Y == y);
foreach(var myClass in query)
    myClass.Unique = false;

如果你真的想要副作用,并且想用linq风格来做,你可以更好地采用流畅的风格来调整你的MyClass,像这样:

public class MyClass
{
  public double X { set; get; }
  public double Y { set; get; }
  public bool Unique { set; get; }
  public MyClass Duplicate()
  {
    Unique = false;
    return this;
  }
}
// So you call:
var query = list.SelectMany(sublist => sublist)
                .Where(item => item.X == x && item.Y == y)
                .Select(item => item.Duplicate());

关于整体结构的几点思考:

看Dictionary<>类。它被设计用来存储可通过任意类型访问的项列表。在这个上下文中使用它:

  • 从你的类中删除唯一性
  • 让你的类成为一个结构体,这样它就可以通过值而不是引用进行比较(即两个具有相同X/Y的不同MyClasses被认为是相同的)
  • 使用Dictionary<MyClass, bool> 代替列表

(似乎需要文本在这里创建一个代码块)

public struct MyClass
{
    public double X { get; set; }
    public double Y { get; set; }
}
var items = new Dictionary<MyClass, Bool>();
items[ new MyClass{ X = 3, Y = 7 } ] = false;
items[ new MyClass{ X = -12, Y = -24 } ] = true;
Assert.IsFalse( items[ new MyClass{ X = 3, Y = 7 } ] );
Assert.IsTrue( items[ new MyClass{ X = -12, Y = -24 } ] );
items[ new MyClass{ X = 3, Y = 7 } ] = true;
Assert.IsTrue( items[ new MyClass{ X = 3, Y = 7 } ] );

说明Dictionary的工作原理:

  • K为"key"类型;这是用于标记要存储在字典中的条目的类型,在将条目放入字典和取出条目时都使用。
  • V为"值"类型;
  • 你可以使用索引器读取或写入字典:
      var value = dictionary[key]
  • dictionary[key] = value
在某些情况下,
  • Dictionary可能比手动遍历列表更快,因为它内部可能使用任何它喜欢的数据结构来搜索匹配,这对于大型数据集可能更快。我相信它使用GetHashCode来筛选匹配项,但在这种情况下,这可能不重要。