1

我正在尝试从选定索引处的传递数组中删除一个值。基本上采用显示数组的列表框的选定索引并使用它来删除条目。由于某种原因,当我运行程序时,什么都没有被删除并且保持不变。我正在用 C# 在 Visual Studio 2010 中编程

public double [] redrawArray(double[] ary, int selectedIndex)
{
    double[] redoneArray = new double[ary.GetUpperBound(0)];

    for (int i = selectedIndex; i < ary.GetUpperBound(0); i++)
    {
        redoneArray[i] = ary[i + 1];
    }
    //redoneArray[ary.GetUpperBound(0)] = 0;
    return redoneArray;
}

这是代码的删除按钮部分

private void btnDelete_Click(object sender, EventArgs e)
{
    int selectedIndex;
    if (this.lstClients.SelectedIndex <= 1)
    {
        return;
    }

    //else if ((this.lstClients.SelectedIndex - 2) < arrayIndex)
    else
    {
            selectedIndex = this.lstClients.SelectedIndex - 2;
            this.lstClients.Items.RemoveAt(this.lstClients.SelectedIndex);
            lbSI.Text = (this.lstClients.SelectedIndex - 2).ToString();
            redrawArray(mFirstNameArray, selectedIndex);
            redrawArray(mLastNameArray, selectedIndex);
            redrawArray(mAgeArray, selectedIndex);
            redrawArray(mHeightArray, selectedIndex);
            redrawArray(mStartWeightArray, selectedIndex);
            redrawArray(mGoalWeightArray , selectedIndex);
            redrawArray(mTotalWeeksArray, selectedIndex);
            //arrayIndex += -1;                    
            lstClients.Items.Clear();
            loadListBox();
    }

}

这是我将其加载到列表中的主要代码

private void loadListBox()
{
    string currentClient;
    int lineNumber = 0;
    string formattedName;
    string strAvgBMI;
    string strLowBMI;
    string strHghBMI;
    double dStartAvgBMI;
    double dStartLowBMI;
    double dStartHghBMI;
    double dEndAvgBMI;
    double dEndLowBMI;
    double dEndHghBMI;


    lstClients.Items.Add("   CLIENT NAME      AGE    HEIGHT(in)   START WEIGHT    START BMI    GOAL WEIGHT    GOAL BMI     WEEKS");
    lstClients.Items.Add("=================  =====  ===========  ==============  ===========  =============  ==========  =========");

    for (int index = 0; index < arrayIndex; index++)
    {
        if (mFirstNameArray[index] == null)
        {
            continue;
        }
        lineNumber++;
        formattedName = mFirstNameArray[index];
        formattedName += " ";
        formattedName += mLastNameArray[index];
        mStartBMI[index] = calcBMI(mHeightArray[index], mStartWeightArray[index]);
        mEndBMI[index] = calcBMI(mHeightArray[index], mGoalWeightArray[index]);
        currentClient = index.ToString() + "   ";
        currentClient += formattedName.PadRight(18) + " ";
        currentClient += mAgeArray[index].ToString("##").PadLeft(4) + "      ";
        currentClient += mHeightArray[index].ToString("##.#0").PadRight(4) + "          ";
        currentClient += mStartWeightArray[index].ToString("###.0").PadRight(4) + "         ";
        currentClient += mStartBMI[index].ToString("##.#0").PadRight(4) + "         ";
        currentClient += mGoalWeightArray[index].ToString("###.0").PadRight(4) + "         ";
        currentClient += mEndBMI[index].ToString("###.#0").PadRight(4) + "       ";
        currentClient += mTotalWeeksArray[index].ToString("##").PadRight(4);

        lstClients.Items.Add(currentClient);
    }
    dStartAvgBMI = sumAvg(mStartBMI, arrayIndex);
    dStartHghBMI = maxArray(mStartBMI, arrayIndex);
    dStartLowBMI = minArray(mStartBMI, arrayIndex);
    dEndAvgBMI = sumAvg(mEndBMI, arrayIndex);
    dEndHghBMI = maxArray(mEndBMI, arrayIndex);
    dEndLowBMI = minArray(mEndBMI, arrayIndex);

    strAvgBMI = "";
    strHghBMI = "";
    strLowBMI =  "";
    strAvgBMI = "                                            Average:      " + dStartAvgBMI.ToString("0#.#0") + "                       " + dEndAvgBMI.ToString("0#.#0");
    strHghBMI = "                                            High:         " + dStartHghBMI.ToString("0#.#0") + "                       " + dEndHghBMI.ToString("0#.#0");
    strLowBMI = "                                            Low:          " + dStartLowBMI.ToString("0#.#0") + "                       " + dEndLowBMI.ToString("0#.#0");
    lstClients.Items.Add(strAvgBMI);
    lstClients.Items.Add(strHghBMI);
    lstClients.Items.Add(strLowBMI);
}
4

5 回答 5

2

您从selectedIndex.. 开始,但新数组不包含任何源数组。这使得一切都在索引之前0。这可以解决Array.Copy

public static double[] redrawArray(double[] ary, int selectedIndex) {
    double[] redoneArray = new double[ary.GetUpperBound(0)];

    Array.Copy(ary, redoneArray, ary.GetUpperBound(0)); // copy the source into the destination minus one..

    for (int i = selectedIndex; i < ary.GetUpperBound(0); i++) {
        redoneArray[i] = ary[i + 1];
    }

    return redoneArray;
}

示例用法:

double[] arr = new double[] {2, 4, 6};

// remove first
arr = redrawArray(arr, 0); // {4, 6}
// remove second
arr = redrawArray(arr, 1); // {2, 6}
// etc..
于 2013-09-15T07:20:37.230 回答
2

我强烈建议使用 aList<double>代替,因为它具有更优雅和更有效的添加和删除项目的策略。

您的算法存在一个重大问题,因为您实际上并没有用来selectedIndex过滤掉“已删除”的项目。我认为它应该看起来像这样

public double[] redrawArray(double[] ary, int selectedIndex)
{
    double[] redoneArray = new double[ary.GetUpperBound(0)];
    int i = 0;
    for (; i < selectedIndex; i++)
    {
        redoneArray[i] = ary[i];
    }
    for (; i < redoneArray.Length; i++)
    {
        redoneArray[i] = ary[i + 1];
    }
    return redoneArray;
}

甚至更好:

public double[] redrawArray(double[] ary, int selectedIndex)
{
    double[] redoneArray = new double[ary.GetUpperBound(0)];
    Array.Copy(ary, redoneArray, selectedIndex);
    Array.Copy(ary, selectedIndex + 1, 
               redoneArray, selectedIndex, redoneArray.Length - selectedIndex);
    return redoneArray;
}

更新

然而,真正的问题是您的redrawArray方法返回一个数组而不是修改现有数组。您必须使用将结果数组分配回您的变量,如下所示:

mFirstNameArray = redrawArray(mFirstNameArray, selectedIndex);
mLastNameArray = redrawArray(mLastNameArray, selectedIndex);
mAgeArray = redrawArray(mAgeArray, selectedIndex);
mHeightArray = redrawArray(mHeightArray, selectedIndex);
mStartWeightArray = redrawArray(mStartWeightArray, selectedIndex);
mGoalWeightArray = redrawArray(mGoalWeightArray , selectedIndex);
mTotalWeeksArray = redrawArray(mTotalWeeksArray, selectedIndex);
于 2013-09-15T07:24:41.353 回答
1

如果您想要一个可以从中删除内容的数组,那么最好使用类似的东西List<double>,这将为您节省很多麻烦。

然后在特定索引处删除,只需调用.RemoveAt(index)

如果您仍想在外部使用 Arrays,您可以“作弊”,使用该array.ToList()功能为自己获取一个列表,删除您想要的任何内容,然后.toArray()将其返回。是的,它的效率很低,但我认为你目前正在做的事情并没有那么快。

于 2013-09-15T07:23:00.303 回答
0
public double[] RedrawArray(double[] ary, int selectedIndex)
{  
    var lst = new List<double>(ary);
    lst.RemoveAt(selectedIndex);
    return lst.ToArray();
}
于 2013-09-15T07:29:14.130 回答
0

使用 Linq,我想您可以:

public double[] RedrawArray(double[] ary, int selectedIndex)
{
  return ary.Where((d, i) => i!=selectedIndex).ToArray();
}

或者:

public void RedrawArray(ref double[] ary, int selectedIndex)
{
  ary = ary.Where((d, i) => i!=selectedIndex).ToArray();
}

取决于调用方法时哪种语法最方便。

请注意,在任何一种情况下,传递给此方法的数组都不应在方法运行时被其他线程修改。在这种ref情况下,如果传递了字段或捕获的变量,则该变量不得由其他线程重新分配。

于 2013-09-15T07:34:41.123 回答