Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 搜索整数数组中的重复项_C#_Arrays - Fatal编程技术网

C# 搜索整数数组中的重复项

C# 搜索整数数组中的重复项,c#,arrays,C#,Arrays,我目前正在用C#创建一个非常基本的游戏,我创建了一个库存系统,使用一个非常简单的命令(Items.Add(id,amount))可以将物品添加到所述库存中。我希望能够做到的是,我当前的系统没有做到的是能够有效地“搜索”我的库存数组,它是一个包含项目id和项目金额的2D数组。我目前的系统是这样的: public static void add(int id, int amount) { for (int i = 0; i < Ship_Builder.Player.invCount;

我目前正在用C#创建一个非常基本的游戏,我创建了一个库存系统,使用一个非常简单的命令(Items.Add(id,amount))可以将物品添加到所述库存中。我希望能够做到的是,我当前的系统没有做到的是能够有效地“搜索”我的库存数组,它是一个包含项目id和项目金额的2D数组。我目前的系统是这样的:

public static void add(int id, int amount)
{
    for (int i = 0; i < Ship_Builder.Player.invCount; i++)
    {
        if (Ship_Builder.Player.inv[i, 0] == 0)
        {
            Ship_Builder.Player.inv[i, 0] = id; 
            Ship_Builder.Player.inv[i, 1] = amount;
        }
    }

    Ship_Builder.Player.invCount++;
}
public class InventoryItem
{
    public int Id { get; set; }
    public int Amount { get; set; }
    // Now I can add other useful properties here too
    // ...like Name perhaps?
}
public void Add(int id, int amount) 
{
    // assuming myInventory is our inventory
    if (myInventory.ContainsKey(id)) {
        myInventory[id].Amount += amount;
    }
    else {
        myInventory[id] = new InventoryItem() 
        {
            Id = id,
            Amount = amount
        };
    }
}
以前,但它没有按照我的要求工作。 任何帮助都将不胜感激,谢谢,
Laurence.

这里有很多事情要做(没有足够的细节来给出任何答案,除了大致的笔划),但我将如何处理类似的事情,将从使用面向对象的设计开始,而不是依赖数组中的索引位置。我会这样定义:

public static void add(int id, int amount)
{
    for (int i = 0; i < Ship_Builder.Player.invCount; i++)
    {
        if (Ship_Builder.Player.inv[i, 0] == 0)
        {
            Ship_Builder.Player.inv[i, 0] = id; 
            Ship_Builder.Player.inv[i, 1] = amount;
        }
    }

    Ship_Builder.Player.invCount++;
}
public class InventoryItem
{
    public int Id { get; set; }
    public int Amount { get; set; }
    // Now I can add other useful properties here too
    // ...like Name perhaps?
}
public void Add(int id, int amount) 
{
    // assuming myInventory is our inventory
    if (myInventory.ContainsKey(id)) {
        myInventory[id].Amount += amount;
    }
    else {
        myInventory[id] = new InventoryItem() 
        {
            Id = id,
            Amount = amount
        };
    }
}
现在,我将我的清单设置为一个
字典
,并向清单中添加一些内容可能如下所示:

public static void add(int id, int amount)
{
    for (int i = 0; i < Ship_Builder.Player.invCount; i++)
    {
        if (Ship_Builder.Player.inv[i, 0] == 0)
        {
            Ship_Builder.Player.inv[i, 0] = id; 
            Ship_Builder.Player.inv[i, 1] = amount;
        }
    }

    Ship_Builder.Player.invCount++;
}
public class InventoryItem
{
    public int Id { get; set; }
    public int Amount { get; set; }
    // Now I can add other useful properties here too
    // ...like Name perhaps?
}
public void Add(int id, int amount) 
{
    // assuming myInventory is our inventory
    if (myInventory.ContainsKey(id)) {
        myInventory[id].Amount += amount;
    }
    else {
        myInventory[id] = new InventoryItem() 
        {
            Id = id,
            Amount = amount
        };
    }
}
现在,您不必实际使用
InventoryItem
类,您可以继续使用
dictional
,但您可能会发现,在使用它的过程中,您更希望使用一些对象

然后,您可能有一个包含所有对象的主词典,只需将它们添加到您的库存中,就可以得到如下结果:

public void Add(InventoryItem item, int amount) 
{
    // assuming myInventory is our inventory
    if (myInventory.ContainsKey(item.Id)) {
        myInventory[item.Id].Amount += amount;
    }
    else {
        myInventory[item.Id] = new InventoryItem(item)   // assuming you added a 
                                                         // copy constructor, for example
        {
            Amount = amount
        };
    }
}

正如评论所建议的那样,您应该使用
字典来完成这样的任务。但是,如果你必须使用一个二维数组,在我们添加任何项之前,它(我假设)预先填充了零,那么像你建议的
if-else
语句就不会起作用。您需要做的是首先遍历数组寻找匹配的
id
,每次
id
不匹配时,您必须检查当前正在检查的
id
是否等于0。如果是,那么您已经遍历了所有“插槽”,其中包含一些项目,但没有找到匹配项,这意味着该项目必须进入另一个空插槽

public static void add(int id, int amount)
{
    for (int i = 0; i < Ship_Builder.Player.invCount; i++)
    {
        if (Ship_Builder.Player.inv[i, 0] != id)
        {
            if (Ship_Builder.Player.inv[i, 0] == 0)
            {
                Ship_Builder.Player.inv[i, 0] = id; 
                Ship_Builder.Player.inv[i, 1] = amount;
                Ship_Builder.Player.invCount++; 

                continue;
            }
        }
        else
        {
            Ship_Builder.Player.inv[i, 1] += amount;

            continue;
        }
    }
}
publicstaticvoidadd(整数id,整数金额)
{
对于(int i=0;i

警告我的答案假设您在具有最小索引的空插槽中找到新项目。此外,如果要删除项并将
id
设置为零,则必须首先遍历整个数组以搜索匹配索引,然后才能分配新项。如果阵列很大,这在时间上可能会非常昂贵。

根据速度性能要求(使用阵列的速度应略高于此要求),您可以将硬编码值和阵列一起跳过。这有几个半高级主题:

public abstract class InventoryItem
// or interface
{
  public abstract string Name { get; }
  public int Count { get; set; }
}

public class InventoryGold : InventoryItem 
{
  public string Name { get { return "Gold" } }
}

public abstract class InventoryWeapon : InventoryItem { }

public class OgreSlayingKnife : InventoryWeapon
{
  public string Name { get { return "Ogre Slaying Knife"; } }
  public int VersusOgres { get { return +9; } }
}

public UpdateCount<Item>(this ICollection<Item> instance, 
  int absoluteCount)
{
  var item = instance.OfType<Item>().FirstOrDefault();

  if (item == null && absoluteCount > 0)
  {
    item = default(Item);
    item.Count = absoluteCount;
    instance.add(item);
  }
  else
  {
    if (absoluteCount > 0)
      item.Count = absoluteCount;
    else
      instance.Remove(item);
  }
}

// Probably should be a Hashset
var inventory = new List<InventoryItem>();

inventory.UpdateCount<InventoryGold>(10);

inventory.UpdateCount<OgreSlayingKnife(1)
公共抽象类InventoryItem
//或接口
{
公共抽象字符串名称{get;}
公共整数计数{get;set;}
}
公共类InventoryGold:InventoryItem
{
公共字符串名称{get{return“Gold”}
}
公共抽象类inventoryWearm:InventoryItem{}
公共级奥格雷斯莱因刀:库存武器
{
公共字符串名称{获取{返回“食人魔屠刀”;}
public int VersusOgres{get{return+9;}}
}
public UpdateCount(此ICollection实例,
整数(绝对计数)
{
var item=instance.OfType().FirstOrDefault();
如果(项==null&&absoluteCount>0)
{
项目=默认(项目);
项目计数=绝对计数;
实例.添加(项);
}
其他的
{
如果(绝对计数>0)
项目计数=绝对计数;
其他的
实例。删除(项目);
}
}
//可能应该是一个哈希集
var inventory=新列表();
存货。更新账户(10);

inventory.UpdateCount为什么使用数组,为什么不使用字典?在搜索这个问题的答案之前,我还没有研究过字典,我真的不想重新编写我的所有子系统(依赖于数组中的库存)是如何工作的……我真的不理解您的“搜索”功能。你能提供一些输入/输出示例吗?@LaurieWalpole:老实说,使用字典不需要太多重构,而且字典可能比你要做的查找要快得多。只需将其设置为字典,而不是尝试使用锯齿状数组,您可以执行
inv[0]=1
您真的应该接受@ErikPhilips的建议并使用字典。2D数组在.NET中不是最容易使用的(锯齿状数组或列表更容易使用),使用字典会使查找速度更快。感谢您提供了令人惊讶的答案,我以后可能会改用字典,但现在我将坚持使用当前系统。我唯一要更改的是枚举的ID。如果说
myInventory[Inventory.Gold]
等,将使代码读/写更加简单。非常感谢您的回答,它返回了一个超出范围的异常,但我现在正在计算-数组的最大长度为50,所以应该可以。