【问题标题】:If Statements Overwriting Previous SetterIf 语句覆盖先前的 Setter
【发布时间】:2023-03-11 04:35:02
【问题描述】:

这可能是一件非常简单的事情,但我已经尝试了一些事情,但无法理解如何防止覆盖 foreach -> if 语句中的值。

我有一个由Entries 组成的文件,其中有单独的Entry。我正在尝试为每个人 Entry 设置不同的值,但目前它正在正确设置它们,但在每次迭代时都会覆盖。

var inputdoc = _service.ConvertToDocument(input);
var journal = _service.ConvertFromDocument(inputdoc);

foreach (var i in inputdoc .Body)
{
            
        foreach (var doc in journal.Entries)
        {
            doc.Entity = entityCode;

            if (doc.Entity == 12345)
            {
                if (i.Number == "VALBEU1") { doc.BankAccount = "435345345"; }
                if (i.Number == "VALBGB1") { doc.BankAccount = "324234234"; }
                if (i.Number == "VALBHU1") { doc.BankAccount = "45342123123"; }
                if (i.Number == "VALBMX1") { doc.BankAccount = "45546231"; }
                if (i.Number == "VALBSE1") { doc.BankAccount = "2344353123"; }
                if (i.Number == "VALBUS1") { doc.BankAccount = "234435645"; }
                if (i.Number == "VALBNO1") { doc.BankAccount = "234233123"; }
            }
        }
  }

所以问题是单个Entry 的最终结果是最终具有相同的 BankAccount 值,而它应该根据i.Number 不同而有所不同。所以我怎么能做到这样当我去的时候通过我的Entries 并设置我的Entry 值,使BankAccount 数字保持不变并移动到下一个条目..设置该值等等..

【问题讨论】:

  • 请阅读how-to-ask page和How to create a Minimal, Complete, and Verifiable example以改进您的问题并帮助我们了解您的问题。
  • 旁注:我建议使用Dictionary<string, string> 而不是一堆if (i.Number == ...)
  • 调试并逐步完成您的逻辑。人们给出了很多小的建议,这些建议是很好的代码审查,但即使是循环迭代的基础知识也没有意义。重新分析您要解决的问题,一次一行地遍历您的代码
  • 问题可能是您似乎有一个不相关的外部for 循环。由于journal 是在该循环之外创建的,因此您为inputdoc.Body 中的每个条目迭代journal.Entities 一次。如果您的代码是幂等的,这无关紧要,但如果您有设置属性的副作用,它可能会搞砸。
  • 轻微优化(不会解决您的问题):使用if (..) {..} else if (..) 链而不是单独的if 语句。或查看switch (i.Number) { case "VALBEU1": ..(或字典,如前所述)

标签: c# for-loop if-statement


【解决方案1】:

您可以压缩这两个序列以创建输入文档和日记条目对。此外,您还可以创建字典以通过输入代码查找帐号。

var accountDict = new Dictionary<string, string>() {
    ["VALBEU1"] = "435345345",
    ["VALBGB1"] = "324234234",
    ["VALBHU1"] = "45342123123",
    ...
};

var inputdoc = _service.ConvertToDocument(input);
var journal = _service.ConvertFromLedger(ledger);

// Create tuples of input docs and journal entries
var inputAndDocs = inputdoc.Body.Zip(journal.Entries, (input, doc) => (input, doc);

foreach (var pair in inputAndDocs)
{
    var doc = pair.doc;
    doc.Entity = entityCode;
    if (doc.Entity == 23380 &&
        accountDict.TryGetValue(pair.input.Number, out var account))
    {
        doc.BankAccount = account;
    }
}

这假定输入文档和日记帐分录必须按给定顺序成对匹配。

您总是分配相同的entityCode,然后在循环内部测试它是否匹配一个常数。由于entityCode 永远不会改变,因此您可以提前进行此测试并完全跳过整个过程。

if (entityCode == 23380) {
    // TODO: initialize
    foreach (var pair in inputAndDocs)
    {
        var doc = pair.doc;
        doc.Entity = entityCode;
        if (accountDict.TryGetValue(pair.input.Number, out var account)) {
            doc.BankAccount = account;
        }
    }
}

为什么你的方法不起作用?我们举个简单的例子:

int[] aArray = { 1, 2, 3 };
int[] bArray = { 10, 20, 30 };
foreach (int a in aArray) {
    foreach (int b in bArray) {
        Console.WriteLine($"{a}, {b}");
    }
}

打印

1, 10
1, 20
1, 30
2, 10
2, 20
2, 30
3, 10
3, 20
3, 30

使用压缩序列和单个 foreach;然而,产量

1, 10
2, 20
3, 30

您也可以使用单个 for 循环来代替 zip 循环

for (int i = 0; i < Math.Min(a.Length, b.Length); i++) {
    Console.WriteLine($"{aArray[i]}, {bArray[i]}");
}

【讨论】:

  • 这太好了,所以可以说我们有不同的实体值,即23381,它们也有自己的accountDict 值.. 我可以继续添加到同一个字典并添加更多 if 语句上面写着 `if(doc.Entity == 23380 &.." ?
  • 您还可以通过使用元组作为键来将字​​典基于值对。像var accountDict = new Dictionary&lt;((int, string), string&gt;() { [(23380 , "VALBEU1")] = "435345345", [(23380 , "VALBGB1")] = "324234234", ... [(23381 , "VALBEU1")] = "895345345", [(23381 , "VALBGB1")] = "774234234", }; 和tretrieve 与元组以及accountDict.TryGetValue((eCode, number), out var account)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-19
  • 1970-01-01
  • 2017-08-03
相关资源
最近更新 更多