簡體   English   中英

如何加入多維數組

[英]How to join to multidimensional array

幾天來我一直在嘗試解決此問題,並且想知道是否有人可以提供幫助,我對C#還是陌生的,因此您可以推薦的任何東西都將為您帶來很大的幫助!

我想做的是將一個新的名稱/分數保存到現有的名稱/分數列表中。

我已經嘗試了許多不同的方法,但是沒有運氣。

以下是我要執行的操作的一個示例:

string[,] array1 = new string[,] { { "Bob", "100" } };
string[,] array2 = new string[,] { { "Dave", "200" }, { "Sam", "300" }, { "nick", "310" } };

所以我將通過下面的函數傳遞兩個數組。

public static string[,] CombineArrayFunction(string[,] array1, string[,] array2)
{

    string[,] finalArray = new string[array1.Length + array2.Length, 2];

    Array.Resize<string[,]>(ref array1, array1.Length + array2.Length);

    Array.Copy(array2, 0, array1, array1.Length, array2.Length);

    for (int i = 0; i < finalArray.Length; i++)
    {
        finalArray[i, 0] = array1[i, 0];
        finalArray[i, 1] = array1[i, 1];
    }

    return finalArray;
}

您可以使用字典。 它比多維數組簡單得多。

var dict1 = new Dictionary<string, string> { { "Bob", "100" } };
var dict2 = new Dictionary<string, string> { { "Dave", "200" }, { "Sam", "300" }, { "Nick", "310" } };
var combinedDict = dict1.Concat(dict2).GroupBy(d => d.Key).ToDictionary(d => d.Key, d => d.First().Value);

foreach (var item in combinedDict)
{
    Console.WriteLine($"{item.Key} - {item.Value}");
}

結果

鮑勃-100
戴夫-200
山姆-300
尼克-310

你不能使用

Array.Resize<string[,]>(ref array1, array1.Length + array2.Length);

因為數組中的元素不是string[,]類型。 如果您有一個string[][]它將起作用,因為這樣您就可以使用

Array.Resize<string[]>(....);

對於多維數組,沒有afaik沒有內置方法,因此您只需“手動”完成操作即可

public static string[,] CombineArrayFunction(string[,] array1, string[,] array2)
{
    var finalArray = new string[array1.Length + array2.Length, 2];

    // simply first run through the one array
    for (var i = 0; i < array1.Length; i++)
    {
        finalArray[i, 0] = array1[i, 0];
        finalArray[i, 1] = array1[i, 1];
    }

    // then run through the second array
    for (var i = 0; i < array2.Length; i++)
    {
        // simply add an offset to the index
        // according to the length of the first array
        finalArray[i + array1.Length - 1, 0] = array2[i, 0];
        finalArray[i + array1.Length - 1, 1] = array2[i, 1];
    }

    return finalArray;
}

但是,也許主要的問題在於您的數據結構本身。


如果您擁有唯一的密鑰,那么Rawitas Krungkaew提到的Dictionary可能是一種更好的方法,因為如果以后您要查找特定的值,那么訪問Dictionary速度也會更快。


如果您的用例僅是關於在某處存儲和顯示此信息,則我實際上建議您使用適當的自定義類型和簡單的平面列表,例如

public List<ScoreEntry> scoreBoard = new List<ScoreEntry>();

[Serializable]
public class ScoreEntry
{
    public string Name;
    // or still string if you want to stick to that
    public int Score;

    public ScoreEntry(string name, int score)
    {
        Name = name;
        Score = score;
    }
}

那么您可以簡單地添加一個項目

scoreBoard.Add(new ScoreEntry("Bob", 100))

或者如果需要使用AddRange多個

scoreBoard.AddRange(new List<ScoreEntry>{new ScoreEntry("Bob", 100), new ScoreEntry("Marley", 200)});

此列表還有很多優點。

例如,可以非常簡單地進行迭代,而不必一直在乎兩個索引。

特別是因為有了計分板,因為您現在可以使用Linq的所有功能using Syste.Linq;並對列表進行過濾和排序。

例如,按字母順序排序此列表

var alphabeticallyOrdererList = scoreBoard.OrderBy(e => e.Name).ToList();

或按分數

var scoreOrderedList = scoreBoard.OrderByDescending(e => e.Score).ToList();

或同時使用按分數排序和如果按名稱排序相等

var scoreAndAlphabeticallyOrderedList = scoreBoard.OrderByDescending(e => e.Score).ThenBy(e => e.Name).ToList();

或返回所有屬於“鮑勃”的條目

var bobEntries = scoreBoard.Where(e => string.Equals(e.Name, "Bob")).ToList();

而且,如果您仍然需要訪問某些條目, Linq提供了很多魔術。 例如,找到"Bob"的最高分

var entry = scoreBoard.Where(e => string.Equals(e.Name, "Bob")).OrderByDescending(e => e.Score).FirstOrDefault();

要么返回最高分數“ Bob”,要么返回0如果列表中沒有分數。


該列表的另一個優點是它可以直接序列化,因此1.您實際上可以在Unity Inspector中看到它。 如果您在檢查器中用一些默認值填充它,它將被保存。

您還可以直接將其序列化和反序列化為大多數格式,例如XML,JSON(對於那些需要列表的包裝類的格式),或者僅在文本文件中,每個條目僅一行,等等。

二維數組並不是最好的數據結構(更多信息請參見@derHugo文章)。 對於實際的代碼,

var finalArray = new string[array1.Length + array2.Length, 2];

array1.Length是所有維度中所有項目的總數。 您真正想要的是array1.GetLength(0)

Array.Resize<string[,]>(ref array1, array1.Length + array2.Length);

您無法調整多維數組的大小。 如果可以,則不需要finalArray,因為無論如何Resize都會創建新的數組。 但是你不能。

Array.Copy(array2, 0, array1, array1.Length, array2.Length);

array1.Length不再保存原始數組的大小。 現在,它返回已調整大小的數組的大小,所以這是一個錯誤。

for (int i = 0; i < finalArray.Length; i++)
{
    finalArray[i, 0] = array1[i, 0];
    finalArray[i, 1] = array1[i, 1];
}

當您可以使用Array.Copy時,真的不需要循環。 這是我的代碼

public static string[,] CombineArrayFunction(string[,] array1, string[,] array2)
{
    if (array1.GetLength(1) != array2.GetLength(1))
    {
        throw new NotSupportedException("Arrays have to be the same size");
    }

    string[,] finalArray = new string[array1.GetLength(0) + array2.GetLength(0), array1.GetLength(1)];

    Array.Copy(array1, 0, finalArray, 0, array1.Length);
    Array.Copy(array2, 0, finalArray, array1.Length, array2.Length);

    return finalArray;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM