简体   繁体   English

尝试从数组中删除单个值

[英]Trying to delete a single value from array

I am trying to delete a value from a passed array at the selected index. 我正在尝试从选定索引处的传递数组中删除一个值。 Basically taking the selected index of a list box that displays the arrays and using it to delete an entry. 基本上,使用显示阵列的列表框的选定索引,并使用它删除条目。 For some reason nothing is deleted and stays the same when I run the program. 由于某种原因,在我运行该程序时,没有任何内容被删除并且保持不变。 I am programing in Visual Studio 2010 in C# 我正在使用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;
}

Here is the delete button portion of code 这是代码的删除按钮部分

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();
    }

}

And here is my main code that loads it into the list 这是我的主要代码,将其加载到列表中

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);
}

You're starting from the selectedIndex .. but the new array doesn't contain any of the source array. 您从selectedIndex ..开始,但是新数组不包含任何源数组。 This makes everything before the index 0 . 这使索引之前的所有内容都为0 This can be solved with Array.Copy . 这可以通过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;
}

Example usage: 用法示例:

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

// remove first
arr = redrawArray(arr, 0); // {4, 6}
// remove second
arr = redrawArray(arr, 1); // {2, 6}
// etc..

I'd strongly recommend using a List<double> instead, since it has a more graceful and efficient strategy for adding and removing items. 我强烈建议改用List<double> ,因为它具有用于添加和删除项目的更优雅,更有效的策略。

There is a significant problem with your algorithm, because you haven't actually used selectedIndex to filter out the 'deleted' item. 您的算法存在一个重大问题,因为您实际上并未使用selectedIndex来过滤掉“已删除”项。 I think it should look like this 我认为应该看起来像这样

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;
}

Or even better: 甚至更好:

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;
}

Update 更新资料

The real problem, however, is that you're redrawArray method returns a new array rather than modifying the existing array. 但是,真正的问题是,您的redrawArray方法将返回一个数组,而不是修改现有数组。 You'd have to use assign the result array back to your variables, like this: 您必须使用将结果数组分配回变量的方式,如下所示:

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);

If you want an array which you can delete things from, then its best to use something like List<double> , which will save you a lot of trouble. 如果您想要一个可以从中删除内容的数组,那么最好使用List<double>类的东西,这将为您节省很多麻烦。

Then to delete at a particular index, just call .RemoveAt(index) 然后要删除特定索引,只需调用.RemoveAt(index)

If you still want to use Arrays externally, you can 'cheat' by using the array.ToList() function to get yourself a list, delete whatever it is you want, and then .toArray() it back. 如果仍然想在外部使用array.ToList() ,则可以使用array.ToList()函数“欺骗”自己,以获取列表,删除所需的内容,然后将.toArray()返回。 Yeah its quite inefficient, but I don't think what you're currently doing is that fast as it is. 是的,它的效率很低,但是我不认为您目前正在做的事情如此之快。

public double[] RedrawArray(double[] ary, int selectedIndex)
{  
    var lst = new List<double>(ary);
    lst.RemoveAt(selectedIndex);
    return lst.ToArray();
}

With Linq I guess you can: 我想借助Linq,您可以:

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

or: 要么:

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

depending on which syntax is most convenient when calling the method. 取决于调用该方法时最方便的语法。

Note that in either case the array passed to this method should not be modified by other threads while the method is running. 请注意,无论哪种情况,传递给该方法的数组都不应在该方法运行时被其他线程修改。 In the ref case, if a field or captured variable was passed, that variable must not be re-assigned by other threads. ref情况下,如果传递了字段或捕获的变量,则该变量不得由其他线程重新分配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM