2015-03-24 80 views
-3

我有3個陣列與下面的數據類型:重新組織出值基於值的唯一組合的陣列的2 C#

string[] arrID = {"111", "222", "333", "444", "555", "666", "777"}; 

DateTime[] arrDates = new DateTime[] 
{ 
    new DateTime(2015, 03, 20), 
    new DateTime(2015, 03, 20), 
    new DateTime(2015, 03, 20), 
    new DateTime(2015, 03, 21), 
    new DateTime(2015, 03, 21), 
    new DateTime(2015, 03, 20), 
    new DateTime(2015, 03, 20) 
}; 

string[] arrTime = {"8:20", "8:40", "8:20", "9:10", "8:20", "9:10", "8:20"}; 

我已經加入樣品的元素到3個陣列,以模擬我們將在這些數組中使用的數據類型。

每個這些元素中的每個索引號都包含與一條記錄相關的值。

示例:每個索引爲3的數組中的值都包含構成一條記錄的值。

我需要把這些3個數組值代入下3個數組:arrNEWIDarrNEWDatearrNEWTime基於下列條件:

  • 對於每個唯一的日期和時間的組合,單獨的元件需要是添加到每個陣列。
  • 如果一個唯一的日期和時間組合具有多個ID,那麼這些ID需要用逗號分隔。
在3個NEW陣列

預期輸出

-------------------------------------------------- 
| index | arrNEWDate | arrNEWTime | arrNEWID  | 
-------------------------------------------------- 
| 0 | 03/20/2015 | 8:20  | 111,333,777 | 
| 1 | 03/20/2015 | 8:40  | 222   | 
| 2 | 03/20/2015 | 9:10  | 666   | 
| 3 | 03/21/2015 | 8:20  | 555   | 
| 4 | 03/21/2015 | 9:10  | 444   | 

注:

  • 在3點新的陣列的數據類型需要是
  • 輸入和輸出需要保持爲數組。列表裏可以用於處理

這裏創建是我已經使用的代碼:

string[] arrID = { "111", "222", "333", "444", "555", "666", "777" }; 

DateTime[] arrDates = new DateTime[] 
{ 
    new DateTime(2015, 03, 20), 
    new DateTime(2015, 03, 20), 
    new DateTime(2015, 03, 20), 
    new DateTime(2015, 03, 21), 
    new DateTime(2015, 03, 21), 
    new DateTime(2015, 03, 20), 
    new DateTime(2015, 03, 20) 
}; 

string[] arrTime = { "8:20", "8:40", "8:20", "9:10", "8:20", "9:10", "8:20" }; 

string str_arrNEWID = ""; 
string str_arrNEWDate = ""; 
string str_arrNEWTime = ""; 
string[] arrNEWID = "".Split('~'); 
string[] arrNEWDate = "".Split('~'); 
string[] arrNEWTime = "".Split('~'); 

for (int i = 0; i <= arrID.GetUpperBound(0); i++) 
{ 
    int intExists = 0; 

    for (int j = 0; j <= arrNEWDate.GetUpperBound(0); j++) 
    { 
     //check if date matches for the current index being checked 
     if (arrNEWDate[j].ToString() == arrDates[i].Date.ToString("MM/dd/yyyy")) 
     { 
      //check if time matches for the same index 
      if (arrNEWTime[j].ToString() == arrTime[i].ToString()) 
      { 
       //existing record 
       intExists = 1; 
       arrNEWID[j] = arrNEWID[j] + "," + arrID[i]; 
       str_arrNEWID = string.Join("~", arrNEWID); 
      } 
     } 

    } 

    if (intExists == 0) 
    { 
     //new record 
     str_arrNEWDate = str_arrNEWDate + "~" + arrDates[i].Date.ToString("MM/dd/yyyy") ; 
     arrNEWDate = str_arrNEWDate.Split('~'); 

     str_arrNEWTime = str_arrNEWTime + "~" + arrTime[i].ToString() ; 
     arrNEWTime = str_arrNEWTime.Split('~'); 

     str_arrNEWID = str_arrNEWID + "~" + arrID[i]; 
     arrNEWID = str_arrNEWID.Split('~'); 
    } 
} 

的主要挑戰是,需要使用編譯這段代碼的編譯器不支持拉姆達運算符(=>)

我需要知道:

  1. 如果有辦法做到這一點,這樣我就不必使用臨時字符串變量和分割功能,每次

  2. 刷新陣列如果有任何的方式來擺脫多重循環的

+1

你有什麼試過?該代碼做了什麼?這與你期望或​​想要做的有什麼不同?請參閱http://stackoverflow.com/help/how-to-ask獲取有關如何以清晰,可回答的方式表達您的問題的建議。 – 2015-03-24 21:22:50

+0

我已添加這些詳細信息。感謝您的時間:) – slayernoah 2015-03-25 03:11:14

+0

問題已經更新。請刪除或解釋投票 – slayernoah 2015-03-25 03:14:14

回答

0

陣列使一切變得更加困難。

using System; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 
using System.Collections.Generic; 
using System.Linq; 

namespace UnitTestProject1 
{ 
    [TestClass] 
    public class UnitTest1 
    { 
     [TestMethod] 
     public void TestMethod1() 
     { 
      string[] arrID = { "111", "222", "333", "444", "555", "666", "777" }; 

      DateTime[] arrDates = new DateTime[] 
      { 
       new DateTime(2015, 03, 20), 
       new DateTime(2015, 03, 20), 
       new DateTime(2015, 03, 20), 
       new DateTime(2015, 03, 21), 
       new DateTime(2015, 03, 21), 
       new DateTime(2015, 03, 20), 
       new DateTime(2015, 03, 20) 
      }; 

      string[] arrTime = { "8:20", "8:40", "8:20", "9:10", "8:20", "9:10", "8:20" }; 

      int i = -1; 
      int index = 0; 
      List<ewansObject> l2 = arrID.Select(o => new ewansObject() { date = arrDates[++i].ToString(), time = arrTime[i], id = arrID[i] }).GroupBy(k => k.date + k.time).Select(o => new ewansObject() { index = index++.ToString(), date = o.First().date, time = o.First().time, id = String.Join(",", o.Select(x => x.id)) }).ToList(); ; 

      string[] arrNEWID = l2.Select(x => x.id).ToArray(); 
      string[] arrNEWDate = l2.Select(x => x.date).ToArray(); 
      string[] arrNEWTime = l2.Select(x => x.time).ToArray(); 

      Console.WriteLine(String.Join("|", arrNEWID)); 
      Console.WriteLine(String.Join("|", arrNEWDate)); 
      Console.WriteLine(String.Join("|", arrNEWTime)); 
     } 

     public class ewansObject 
     { 
      public string index; 
      public string date; 
      public string time; 
      public string id; 
     } 
    } 
} 

也許我應該改變我的名字homework4points

+0

謝謝。然而,是否有可能做到這一點,而不使用lambda運算符? – slayernoah 2015-03-25 03:12:15

0

那種處理你所追求的是非常容易被.NET的LINQ功能處理的。特別是,LINQ包含非常方便的group...byorderby,它們直接適用於您的場景。不幸的是,正常的LINQ語法在很大程度上依賴於lambda語法,你說你不能使用它。

但是,請注意,lambda語法只是一個「語法糖」,即向編譯器表達一些東西,您可以用更詳細的方式編寫自己的東西。特別是,這裏使用的lambda語法生成匿名方法,您當然可以將其寫爲命名方法。

匿名方法還允許變量「捕捉」,但在你的情況下,我們能夠避免需要做兩兩件事來捕獲任何變量:

  1. 放入類字段中的數據,已命名的方法可以訪問他們
  2. 使用Enumerable.Select()重載傳遞一個索引到選擇的方法,以使命名的方法可以在涉及每一個

同樣,其它兩個陣列相關與元件的源項,而匿名類型在這裏很方便,那些依賴匿名方法的有效使用和推斷這些匿名方法的方法參數的類型。取而代之的是,Tuple課程也可以提供。

把所有的一起,我們得到的東西看起來是這樣的:

class Program 
{ 
    static readonly string[] arrID = { "111", "222", "333", "444", "555", "666", "777" }; 

    static readonly DateTime[] arrDates = new DateTime[] 
    { 
     new DateTime(2015, 03, 20), 
     new DateTime(2015, 03, 20), 
     new DateTime(2015, 03, 20), 
     new DateTime(2015, 03, 21), 
     new DateTime(2015, 03, 21), 
     new DateTime(2015, 03, 20), 
     new DateTime(2015, 03, 20) 
    }; 

    static readonly string[] arrTime = { "8:20", "8:40", "8:20", "9:10", "8:20", "9:10", "8:20" }; 

    static void Main(string[] args) 
    { 
     // Generate intermediate query with grouped, ordered data 
     Tuple<DateTime, string>[] q = arrID.Select(CreateRecord) 
      .GroupBy(GetKey) 
      .OrderBy(GetGroupKey) 
      .Select(FlattenGroup) 
      .ToArray(); 

     // Final output arrays here 
     string[] str_arrNEWDate = new string[q.Length], 
      str_arrNEWTime = new string[q.Length], 
      str_arrNEWID = new string[q.Length]; 

     for (int i = 0; i < q.Length; i++) 
     { 
      str_arrNEWDate[i] = q[i].Item1.ToString("MM/dd/yyyy"); 
      str_arrNEWTime[i] = q[i].Item1.ToString("HH:mm"); 
      str_arrNEWID[i] = q[i].Item2; 

      // Diagnostic for demonstration purposes 
      Console.WriteLine("{0}: {1}", q[i].Item1, q[i].Item2); 
     } 
    } 

    private static Tuple<DateTime, string> CreateRecord(string id, int index) 
    { 
     return Tuple.Create(arrDates[index] + TimeSpan.Parse(arrTime[index]), id); 
    } 

    private static DateTime GetKey(Tuple<DateTime, string> record) 
    { 
     return record.Item1; 
    } 

    private static DateTime GetGroupKey(IGrouping<DateTime, Tuple<DateTime, string>> group) 
    { 
     return group.Key; 
    } 

    private static Tuple<DateTime, string> FlattenGroup(IGrouping<DateTime, Tuple<DateTime, string>> group) 
    { 
     return Tuple.Create(group.Key, string.Join(",", group.Select(GetId))); 
    } 

    private static string GetId(Tuple<DateTime, string> record) 
    { 
     return record.Item2; 
    } 
} 

正如你所看到的,到處都是,你通常會寫一個lambda表達式,在上面的,而不是我們只是一個普通static方法做這項工作。請注意,如果您正在處理非static類以及訪問實例成員所需的方法,則可以簡單地將這些方法設爲非static

委託類型推斷負責構造需要傳遞給LINQ方法的委託實例。


注:,而你沒有在你的問題說的那麼明確,規範的性質強烈暗示,這是家庭作業。因此,您應該確保您花時間去了解瞭解上面的代碼示例。否則,你什麼也學不到,浪費你在課堂上的時間。請隨時在這裏提出有關我的答案的問題,當然,您應該很樂意請您的老師幫助您瞭解原始作業和此答案。