【问题标题】:How can I get the sum (average) value of three lists in C#?如何在 C# 中获取三个列表的总和(平均值)?
【发布时间】:2014-03-05 16:04:48
【问题描述】:

我有三个列表,每个列表仅代表与三个图像的像素值相关的 0 和 1。 我的问题是如何获得这三个列表的总和(平均值)并在新列表中表示它? 这是我的 image1 的示例:

List<int> image1 = new List<int>();
        int blackColor = 0;

        for (int x = 0; x < bmp1.Width; x++)
        {
            for (int y = 0; y < bmp1.Height; y++)
            {
                Color color = bmp1.GetPixel(x, y);

                if (color.ToArgb() == Color.Black.ToArgb())
                {
                    image1.Add(0);
                    blackColor++;                        
                }
                else
                {
                    image1.Add(1);
                }
            }
        }

【问题讨论】:

  • 你会想看看 SelectMany
  • 你能给我一些资源或例子吗?
  • Grant Winney;不,基本上我需要做的是获取所有零元素(列表的零元素)的平均值并将其放入新列表中,因此对于所有所有三个列表的元素。
  • SelectMany 将列表扁平化为一个列表。从那里你只需调用它们的平均值(linq)。这是关于 SelectMany 的帖子:dotnetperls.com/selectmany
  • (切线相关:您可能会发现在循环中使用 GetPixel() 对于大图像来说太慢了。如果是这样,请考虑使用 Bitmap.LockBits()

标签: c# image list average


【解决方案1】:

让我确保我理解问题所在。您有三个长度相同的列表:

list A:  1, 2, 4, 3
list B:  3, 2, 4, 1
List C:  2, 7, 1, 8

并且您希望获得第三个列表,该列表是每个列表的平均值:

List D:  2, 4, 3, 4

是吗?

这是一个 zip 连接的工作。

var sumOfFirstTwo = list1.Zip(list2, (x, y)=>x + y);

sumOfFirstTwo 现在是前两个列表之和的序列。

var sumOfAllThree = sumOfFirstTwo.Zip(list3, (x, y)=>x + y);

sumOfAllThree 现在是所有三个列表之和的序列。

var average = sumOfAllThree.Select(x=>x/3).ToList();

有意义吗?

【讨论】:

  • 埃里克·利珀特;您对问题的理解是正确的,但是据我了解, zip 最多只能占用两个输入。但如果我有超过 5 个列表,我该怎么办?你认为这种方法有效吗?!
  • @user3379918:你说你有三个列表;如果您要问的问题是“我有任意数量的列表,我如何将它们压缩在一起”,那是一个完全不同的问题,所以提出一个新问题。至于任何操作是否“高效”:效率定义为产生的价值除以消耗的资源。因为我不知道你看重什么,或者你想保护什么资源,所以我和世界上除了你之外的其他所有人都无法回答这个问题。
  • 如果你不知道列表的数量,让它成为一个递归函数。
  • @Brandon:这听起来像是一个任意深度的递归;如果有一万个列表怎么办?我们不想递归一万次。
  • @MoslemBenDhaou:拉链连接需要两个序列,通常长度相等,然后连接两个序列的第一个项目,然后是第二个,然后是第三个......就像拉链的两半连接在一起。
【解决方案2】:

这适用于任意数量的列表

var firstList = new[] { 1, 2, 3, 1 };
var secondList = new[] { 2, 3, 1, 1 };
var thirdList = new[] { 3, 1, 2, 2 };
var lists = new[] { firstList, secondList, thirdList };

var listLengths = lists.Select(x => x.Count());
if (listLengths.Distinct().Count() != 1)
    throw new Exception("Line lengths must be the same");
var lengthOfEachList = listLengths.First();
var averages = new List<double>();
for (var i = 0; i != lengthOfEachList; ++i) {
    averages.Add(lists.Average(x => x[i]));
}

LINQ 方式是

var averages = Enumerable.Range(0, lengthOfEachList).Select(x => lists.Average(y => y[x]));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-25
    • 1970-01-01
    • 2021-10-25
    • 2022-01-17
    • 1970-01-01
    • 2020-10-02
    • 2014-04-20
    • 1970-01-01
    相关资源
    最近更新 更多