C# 如何以最佳方式替换列表项
我已经像上面那样更换了。除了这一种,还有其他最好的放置比较的方法吗?您可以让它更可读、更高效:C# 如何以最佳方式替换列表项,c#,C#,我已经像上面那样更换了。除了这一种,还有其他最好的放置比较的方法吗?您可以让它更可读、更高效: if (listofelements.Contains(valueFieldValue.ToString())) { listofelements[listofelements.IndexOf(valueFieldValue.ToString())] = value.ToString(); } 这只需要一次索引。您的方法首先使用Contains,它需要循环所有项目(在最坏的情况下),然后使用
if (listofelements.Contains(valueFieldValue.ToString()))
{
listofelements[listofelements.IndexOf(valueFieldValue.ToString())] = value.ToString();
}
这只需要一次索引。您的方法首先使用
Contains
,它需要循环所有项目(在最坏的情况下),然后使用IndexOf
,它需要再次枚举项目。您需要访问列表两次以替换一个元素。我认为简单的for
循环就足够了:
string oldValue = valueFieldValue.ToString();
string newValue = value.ToString();
int index = listofelements.IndexOf(oldValue);
if(index != -1)
listofelements[index] = newValue;
var key=valueFieldValue.ToString();
for(int i=0;i
我不知道它是否最好,但你也可以使用它
var key = valueFieldValue.ToString();
for (int i = 0; i < listofelements.Count; i++)
{
if (listofelements[i] == key)
{
listofelements[i] = value.ToString();
break;
}
}
列表数据=新列表
(新字符串[]{“计算机”、“A”、“B”、“计算机”、“B”、“A”});
int[]index=Enumerable.Range(0,data.Count)。其中
(i=>data[i]==“计算机”).ToArray();
ForEach(索引,i=>data[i]=“Calculator”);
使用Lambda查找列表中的索引,并使用此索引替换列表项
List<string> data = new List<string>
(new string[] { "Computer", "A", "B", "Computer", "B", "A" });
int[] indexes = Enumerable.Range(0, data.Count).Where
(i => data[i] == "Computer").ToArray();
Array.ForEach(indexes, i => data[i] = "Calculator");
List listofstring=新列表{“abc”、“123”、“ghi”};
listOfStrings[listOfStrings.FindIndex(ind=>ind.Equals(“123”))]=“def”;
使用FindIndex
和lambda查找并替换您的值:
List<string> listOfStrings = new List<string> {"abc", "123", "ghi"};
listOfStrings[listOfStrings.FindIndex(ind=>ind.Equals("123"))] = "def";
为什么不使用扩展方法呢 考虑以下代码:
int j = listofelements.FindIndex(i => i.Contains(valueFieldValue.ToString())); //Finds the item index
lstString[j] = lstString[j].Replace(valueFieldValue.ToString(), value.ToString()); //Replaces the item by new value
var intArray=newint[]{0,1,1,2,3,4};
//替换第一个实例并返回索引
var指数=intArray.Replace(1,0);
// {0, 0, 1, 2, 3, 4}; 索引=1
var stringList=新列表{“a”、“a”、“c”、“d”};
stringList.ReplaceAll(“a”、“b”);
//{“b”、“b”、“c”、“d”};
var intEnum=intArray.Select(x=>x);
intEnum=intEnum.Replace(0,1);
// {0, 0, 1, 2, 3, 4} => {1, 1, 1, 2, 3, 4}
- 没有代码重复
- 不需要键入长linq表达式
- 不需要额外使用
var intArray = new int[] { 0, 1, 1, 2, 3, 4 };
// Replaces the first occurance and returns the index
var index = intArray.Replace(1, 0);
// {0, 0, 1, 2, 3, 4}; index=1
var stringList = new List<string> { "a", "a", "c", "d"};
stringList.ReplaceAll("a", "b");
// {"b", "b", "c", "d"};
var intEnum = intArray.Select(x => x);
intEnum = intEnum.Replace(0, 1);
// {0, 0, 1, 2, 3, 4} => {1, 1, 1, 2, 3, 4}
namespace System.Collections.Generic
{
公共静态类扩展
{
公共静态int Replace(此IList源、T oldValue、T newValue)
{
if(source==null)
抛出新ArgumentNullException(nameof(source));
var index=source.IndexOf(旧值);
如果(索引!=-1)
来源[索引]=新值;
收益指数;
}
公共静态void ReplaceAll(此IList源、T oldValue、T newValue)
{
if(source==null)
抛出新ArgumentNullException(nameof(source));
int指数=-1;
做
{
索引=source.IndexOf(oldValue);
如果(索引!=-1)
来源[索引]=新值;
}而(索引!=-1);
}
公共静态IEnumerable替换(此IEnumerable源、T oldValue、T newValue)
{
if(source==null)
抛出新ArgumentNullException(nameof(source));
返回source.Select(x=>EqualityComparer.Default.Equals(x,oldValue)?newValue:x);
}
}
}
添加了前两个方法以就地更改引用类型的对象。当然,您可以对所有类型使用第三种方法
另外,由于,我添加了ReplaceAll方法。或者,根据Rusian L.的建议,如果您要搜索的项目可以多次出现在列表中:
namespace System.Collections.Generic
{
public static class Extensions
{
public static int Replace<T>(this IList<T> source, T oldValue, T newValue)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
var index = source.IndexOf(oldValue);
if (index != -1)
source[index] = newValue;
return index;
}
public static void ReplaceAll<T>(this IList<T> source, T oldValue, T newValue)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
int index = -1;
do
{
index = source.IndexOf(oldValue);
if (index != -1)
source[index] = newValue;
} while (index != -1);
}
public static IEnumerable<T> Replace<T>(this IEnumerable<T> source, T oldValue, T newValue)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
return source.Select(x => EqualityComparer<T>.Default.Equals(x, oldValue) ? newValue : x);
}
}
}
[Extension()]
公共void ReplaceAll(列表输入、T搜索、T替换)
{
int i=0;
做{
i=input.FindIndex(i,s=>EqualityComparer.Default.Equals(s,search));
如果(i>-1){
输入(i)=替换;
继续;
}
打破
}虽然(正确);
}
按照rokkuchan的回答,只需稍微升级一下:
[Extension()]
public void ReplaceAll<T>(List<T> input, T search, T replace)
{
int i = 0;
do {
i = input.FindIndex(i, s => EqualityComparer<T>.Default.Equals(s, search));
if (i > -1) {
FileSystem.input(i) = replace;
continue;
}
break;
} while (true);
}
List listofstring=新列表{“abc”、“123”、“ghi”};
int index=listOfStrings.FindIndex(ind=>ind.Equals(“123”);
如果(索引>-1)
listOfStrings[index]=“def”;
我认为最适合快速、简单地完成它
List<string> listOfStrings = new List<string> {"abc", "123", "ghi"};
int index = listOfStrings.FindIndex(ind => ind.Equals("123"));
if (index > -1)
listOfStrings[index] = "def";
var d = Details.Where(x => x.ProductID == selectedProduct.ID).SingleOrDefault();
OrderDetail dd = d;
dd.Quantity++;
Details.Remove(d);
您可以使用基于谓词条件的下一个扩展:
if (idx > -1)
Details.Insert(idx, dd);
else
Details.Insert(Details.Count, dd);
因此,您的这些扩展案例可以通过以下方式解决:
if (argName == null) throw new ArgumentNullException(nameof(argName));
可以像这样使用lambda表达式
string targetString = valueFieldValue.ToString();
listofelements.Replace(x => x.Equals(targetString), value.ToString());
@gzaxx。“您正在访问列表两次以替换一个元素。我认为简单for循环应该足够了。”。您在for-loop-mate中访问了多少次该列表?@Pap对不起,我说得不够清楚。他迭代他的列表两次(第一次是检查项目是否在列表中,第二次是获取项目索引)!如果该项目不在collectionsplus中,请使用FindIndex。这是IMHO的最佳通用答案,因为它也可用于比较对象。请参阅。虽然对于一个简单的
Equals
测试,良好的旧IndexOf
也同样有效,并且更简洁-如中所示。这是查找文本(整数、字符串)的正确答案,但对于查找对象不是很好。但是,我更喜欢rokkuchan的答案,因为它是通用的。@SimchaKhabinsky:也适用于引用类型,该类型只需要覆盖等于
,否则只有当对象是相同的引用时,才能找到它。请注意,string
也是一个对象(引用类型)。是的,您是对的。然而,我看到许多开发人员忘记了实现Equals
,您还必须记住,有时您必须同时实现GetHashCode
@SimchaKhabinsky:是的,如果您覆盖Equals
,您应该始终覆盖GetHashCode
,但是GetHashCodeif (argName == null) throw new ArgumentNullException(nameof(argName));
string targetString = valueFieldValue.ToString();
listofelements.Replace(x => x.Equals(targetString), value.ToString());
int index = listOfElements.FindIndex(item => item.Id == id);
if (index != -1)
{
listOfElements[index] = newValue;
}