首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于查找表为数组元素赋值

基于查找表为数组元素赋值
EN

Code Review用户
提问于 2019-04-26 10:52:53
回答 1查看 189关注 0票数 3

我正在编写一个C#程序,在这个程序中,我需要使用元数据填充一个基于查找表和一组字符串数组的数组。我的查找表如下所示(带有键的表:发射器,值:接收器数组):

代码语言:javascript
复制
{
    LED1: ["px1","px2","px3"],
    LED2: ["px4","px5","px6"]
}

我的元数组看起来像这样(它是动态的(只是一个例子),并作为来自DB查询的响应):

代码语言:javascript
复制
var transmitters = new string[] { "LED1", "LED2" };
var receivers = new string[] { "px1", "px2", "px3", "px4", "px5", "px6" };

我的要求是:

  • 如果发射机LED1或LED2 (或任何其他发射机)存在于查找表中,则必须将发射机(即“px1”“px2”“px3”)的值与存在于查找和引导中的接收机进行比较。
  • 孤儿发射机或/接收器必须标记为红色。

示例

查找

代码语言:javascript
复制
{
        LED1: ["px1", "px2", "px3"],
        LED2: ["px5", "px8"]
}

发射机和接收器

代码语言:javascript
复制
var transmitters = new string[] { "led1", "led2" };
var receivers = new string[] { "px1", "px2", "px3", "px4", "px5", "px6" };

结果应该是一份清单如下:

代码语言:javascript
复制
led1-yellow
px1-yellow
px2-yellow
px3-yellow
led2-yellow
px5-yellow
px4-red
px6-red.

我编写的代码可以:

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Linq;


public class Program
{
    public static void Main()
    {
      var transmitters = new string[] { "led1", "led2", "led3" };
      var receivers = new string[] { "px1", "px2", "px3", "px4", "px5", "px6" };
      var lookup = new Dictionary<string, string[]>() {
          { "led1", new string[] { "px1", "px2", "px3" } },
          { "led2", new string[] { "px5", "px8"} }
      };

      var blocks = new List<Block>();
      var blocksTracker = new List<string>();

      foreach (var transmitter in transmitters)
      {
        if (lookup.ContainsKey(transmitter))
        {
          var receiverLookup = lookup[transmitter];
          var intersection = receivers.Intersect(receiverLookup).ToArray();
          if (intersection.Length > 0)
          {
             blocks.Add(new Block() { Id = transmitter, status = "yellow"});
             blocksTracker.Add(transmitter);
            foreach (var receiver in intersection)
            {
              blocks.Add(new Block(){Id = receiver, status = "yellow"});
              blocksTracker.Add(receiver);
            }
          } else  
          {
            blocks.Add(new Block(){Id = transmitter, status = "red"});
            blocksTracker.Add(transmitter);   
          }
        }
      }

      var ungrouped = receivers.Except(blocksTracker).ToArray();

      foreach (var receiver in ungrouped)
      {
        blocks.Add(new Block(){Id = receiver, status = "red"});
        blocksTracker.Add(receiver);
      }

      foreach (var i in blocks)
      {
        Console.WriteLine(i.Id + "-"+i.status);
      }
    }

    public class Block
    {
      public string Id { get; set; }

      public string status { get; set; }
    }
}

我是C#的新手,我想知道是否有更好的方法来做到这一点。您可以看到工作Fiddle 这里

EN

回答 1

Code Review用户

回答已采纳

发布于 2019-04-26 11:52:51

if (lookup.ContainsKey(transmitter)) { var receiverLookup = lookup[transmitter];

这将搜索两次KeyValuePair。有一种更有效的方法:

代码语言:javascript
复制
        if (lookup.TryGetValue(transmitter, out var receiverLookup))

var ungrouped = receivers.Except(blocksTracker).ToArray(); foreach (var receiver in ungrouped) { blocks.Add(new Block(){Id = receiver, status = "red"}); blocksTracker.Add(receiver); }

这里的ToArray()是不必要的:枚举可以保留为惰性枚举,因为惟一的用途是对它进行一次迭代。

var intersection = receivers.Intersect(receiverLookup).ToArray(); if (intersection.Length > 0) { blocks.Add(new Block() { Id = transmitter, status = "yellow"}); blocksTracker.Add(transmitter); foreach (var receiver in intersection) { blocks.Add(new Block(){Id = receiver, status = "yellow"}); blocksTracker.Add(receiver); } } else { blocks.Add(new Block(){Id = transmitter, status = "red"}); blocksTracker.Add(transmitter); }

这似乎相当复杂。我认为整件事可以简化:

代码语言:javascript
复制
var transmittersPaired = new HashSet<string>();
var receiversPaired = new HashSet<string>();

foreach (var transmitter in transmitters)
{
    if (lookup.TryGetValue(transmitter, out var receiverLookup) && receiverLookup.Any())
    {
        transmittersPaired.Add(transmitter);
        foreach (var receiver in receiverLookup)
        {
            receiversSeen.Add(receiver);
        }
    }
}

var blocks = new List<Block>();
foreach (var transmitter in transmitters)
{
    blocks.Add(new Block { Id = transmitter, status = transmittersPaired.Contains(transmitter) ? "yellow" : "red" });
}
foreach (var receiver in receivers)
{
    blocks.Add(new Block { Id = receiver, status = receiversPaired.Contains(receiver) ? "yellow" : "red" });
}

还有一些重复的代码,这些代码可以通过两种方式中的一种进行简化。如果能够保证发射机和接收器永远不会共享If,那么transmittersPairedreceiversPaired就可以合并成一个集合,最后的foreach循环可以在transmitters.Concat(receivers)上合并成一个循环。或者,可以将一个方法考虑在内。

票数 7
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/219172

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档