【问题标题】:How can I merge multiple Arrays into one?如何将多个数组合并为一个?
【发布时间】:2017-10-04 00:07:05
【问题描述】:

我正在尝试将所有 11 个数组合并为一个大数组。所有数组都具有相同数量的元素,并且每个数组中的所有元素都对应于其他数组中的元素。例如,Days 数组的第一个元素对应 Depths 数组的第一个元素,IRIS_IDs 数组的第一个元素,Latitudes 数组的第一个元素等等。

当合并后的数组显示在控制台屏幕上时,它应该如下所示:

我正在从包含相应数据的单独文本文件中将数据读入每个数组中

*编辑 - 我需要这样做,以便能够搜索与特定月份对应的所有数据。例如,如果我选择输入一月,控制台将显示与一月对应的所有数据。因此,在本例中,将显示 1 月份发生的所有地震数据。

【问题讨论】:

  • 看看Zip
  • 对于显示,您不需要合并数组。您需要数组还是只显示特定格式的数据?
  • 您不想将数组“合并”为一个,而是想从数组中创建一个复杂的结构。
  • 请注意,您的问题出在重建数据之前,如果所有这些文件都包含数据“行”的“列”,那么与其将每个文件保存在不同的文件中,不如将其保存为行在文件中,为每一列使用某种形式的分隔符(这样你就可以使用 String.Split),或者更好地序列化正确格式化的日期。
  • 是否有理由不能将数据存储在 XML 或 CSV 文件中,并将它们作为节点或逗号分隔值读回单个数组中。我会避免使用字符串数组,而是查看 List 对象。多维数组也是一种选择,但它们可能难以管理且资源匮乏。

标签: c# arrays merge


【解决方案1】:

您可以创建一个类来聚合您想要显示的所有字段,然后遍历所有元素,并为每次迭代创建此类的新实例并添加到列表中。比如:

Class Merge
{
   public int Days {get; set;}
   public int Depths {get; set;}
etc...
}

for (int i = 0; i < Days; i++)
{
   var merge = new Merge(){Days = Days[0], Depths = Depths[0], ...}

   mergedList.Add(merge);
}

【讨论】:

    【解决方案2】:

    如果您只需要压缩以便打印数据,您也可以:

    var maxItems = (new int[] { Days.Length, Depths.Length, IRIS_IDs.Length,Latitudes.Length })
                   .Max();
    
    var result = Enumerable.Range(0, items)
              .Select(i => string.Join("\t", new [] { Days.ElementAtOrDefault(i),
                                                     Depths.ElementAtOrDefault(i),
                                                     IRIS_IDs.ElementAtOrDefault(i),
                                                     Latitudes.ElementAtOrDefault(i) }));
    

    但是您似乎想对集合执行操作,而不是仅仅串联创建自定义对象以正确包含数据:

    public class Data
    {
        public string Day { get; set; }
        public string Depth { get; set; }
        public string IRIS_ID { get; set; }
        public string Latitude { get; set; }
    
        public override string ToString()
        {
            return $"{Day}, {Depth}, {IRIS_ID}, {Latitude}";
        }
    }
    

    然后你可以:

    var maxItems = (new int[] { Days.Length, Depths.Length, IRIS_IDs.Length,Latitudes.Length })
                   .Max();
    
    var reuslt = Enumerable.Range(0, maxItems)
              .Select(i => new Data
              {
                  Day = Days.ElementAtOrDefault(i),
                  Depth = Depths.ElementAtOrDefault(i),
                  IRIS_ID = IRIS_IDs.ElementAtOrDefault(i),
                  Latitude = Latitudes.ElementAtOrDefault(i)
              }).ToList();
    

    此实现将通过“尽力而为”来填充所有对象的所有数据 - 因此,如果在某些文件中缺少记录,则相应对象中将有 null

    【讨论】:

    • @Illimar - 这对您的问题有帮助吗?
    【解决方案3】:

    示例被简化为 2 个数组。

    类似这样的:

    string[] Days = System.IO.File.ReadAllLines(@"C: \Users\Illimar\Desktop\Algorithms and Comlexity2\Day_1.txt");
    string[] Depths = System.IO.File.ReadAllLines(@"C: \Users\Illimar\Desktop\Algorithms and Comlexity2\Depth_1.txt");
    ...
    
    string[] newArray = new string[Days.Length];
    for(int x = 0; x < Days.Length;x++)
    {
         newArray[x] = string.Format("{0} {1}", Days[x], Depths[x]);
    }
    

    【讨论】:

      【解决方案4】:

      我会用一个新的数据对象列表来解决这个问题。您可能希望循环并在每个数组中创建一个具有相同迭代器的新对象。

      首先创建你的新对象:

      public class MyDataObject
      {
          public string Days { get; set; }
          public string Depth { get; set; }
          public string IRIS_IDs { get; set; }
          public string Latitudes { get; set; }
          // etc ...
      }
      

      然后设置执行循环的函数:

      public IEnumerable<MyDataObject> MyObjectBuilder()
      {
          // Declare return object
          var result = new List<MyDataObject>();
      
          // Get your data 
          string[] Days = System.IO.File.ReadAllLines(@"C: \Users\Illimar\Desktop\Algorithms and Comlexity2\Day_1.txt");
          string[] Depths = System.IO.File.ReadAllLines(@"C: \Users\Illimar\Desktop\Algorithms and Comlexity2\Depth_1.txt");
          string[] IRIS_IDs = System.IO.File.ReadAllLines(@"C: \Users\Illimar\Desktop\Algorithms and Comlexity2\IRIS_ID_1.txt");
          string[] Latitudes = System.IO.File.ReadAllLines(@"C: \Users\Illimar\Desktop\Algorithms and Comlexity2\Latitude_1.txt");
          // etc ...
      
          // Loop through items to build objects
          for(var i = 0; i <= Days.length(); i++)
          {
              result.Add(new MyDataObject {
                  Days = Days[i],
                  Depths = Depths[i],
                  IRIS_IDs = IRIS_IDs[i],
                  Latitudes = Latitudes[i],
                  // etc ...
              }
          }
      
          // Return result
          return result;
      }
      

      【讨论】:

        【解决方案5】:

        你也可以这样做

         string[] Days = System.IO.File.ReadAllLines(@"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\Day_1.txt");
                string[] Depths = System.IO.File.ReadAllLines(@"C: \Users\Illimar\Desktop\Algorithms and Comlexity2\Depth_1.txt");
                string[] IRIS_IDs = System.IO.File.ReadAllLines(@"C: \Users\Illimar\Desktop\Algorithms and Comlexity2\IRIS_ID_1.txt");
                string[] Latitudes = System.IO.File.ReadAllLines(@"C: \Users\Illimar\Desktop\Algorithms and Comlexity2\Latitude_1.txt");
        
                List<string> result = new List<string>();
                (new[] { Days, Depths, IRIS_IDs, Latitudes }).ToList().ForEach(a => result.AddRange(a));
        

        【讨论】:

          【解决方案6】:

          这里有两种方法可以实现您想要的。如您所问,第一个解决方案是使用数组,另一个使用字典。

          在任何一种情况下,使用枚举定义数据文件类型:

          enum DataFileType
          {
              Days = 0,
              Depths,
              IRIS_IDs,
              Latitudes,
              Longitudes,
              Magnitudes,
              Months,
              Regions,
              Times,
              Timestamps,
              Years
          }
          

          对于数组解决方案,我们将使用 DataFileType 定义文件路径数组并创建并行数据数组:

          static readonly string[] FileSpecs = new string[]
          {
              @"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\Day_1.txt" ,
              @"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\Depth_1.txt" ,
              @"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\IRIS_ID_1.txt" ,
              @"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\Latitude_1.txt" ,
              @"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\Longitude_1.txt" ,
              @"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\Magnitude_1.txt" ,
              @"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\Month_1.txt" ,
              @"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\Region_1.txt" ,
              @"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\Time_1.txt" ,
              @"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\Timestamp_1.txt" ,
              @"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\Year_1.txt"
          };
          
          static void Main(string[] args)
          {
              string[][] data = new string[FileSpecs.Length][];
              // read the data
              for (int i = (int)DataFileType.Days; i <= (int)DataFileType.Years; i++)
                  data[i] = System.IO.File.ReadAllLines(FileSpecs[i]);
          
              // grab some data
              string[] IRIS_IDs = data[(int)DataFileType.IRIS_IDs];
          }
          

          这个数组解决方案很好 - 但不是很灵活,将 DataFileType 转换为 int 是乏味

          使用字典提供了更多的灵活性:

          static readonly Dictionary<DataFileType, string> FileMap = new Dictionary<DataFileType, string> {
              { DataFileType.Days, @"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\Day_1.txt" },
              { DataFileType.Depths, @"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\Depth_1.txt" },
              { DataFileType.IRIS_IDs, @"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\IRIS_ID_1.txt" },
              { DataFileType.Latitudes, @"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\Latitude_1.txt" },
              { DataFileType.Longitudes, @"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\Longitude_1.txt" },
              { DataFileType.Magnitudes, @"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\Magnitude_1.txt" },
              { DataFileType.Months, @"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\Month_1.txt" },
              { DataFileType.Regions, @"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\Region_1.txt" },
              { DataFileType.Times, @"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\Time_1.txt" },
              { DataFileType.Timestamps, @"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\Timestamp_1.txt" },
              { DataFileType.Years, @"C:\Users\Illimar\Desktop\Algorithms and Comlexity2\Year_1.txt" }
          };
          
          static void Main(string[] args)
          {
              // read data - map FileDataType to data file content
              var dataMap = new Dictionary<DataFileType, string[]>();
              foreach (var kv in FileMap)
                  dataMap[kv.Key] = System.IO.File.ReadAllLines(kv.Value);
              // grab some data
              string[] data = dataMap[DataFileType.IRIS_IDs];
          }
          

          两者都不是最终的解决方案,但应该会给你一些想法。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-04-20
            • 2018-04-18
            • 1970-01-01
            • 2015-11-11
            • 2017-01-11
            相关资源
            最近更新 更多