Как заменить элемент списка наилучшим образом
if (listofelements.Contains(valueFieldValue.ToString()))
{
listofelements[listofelements.IndexOf(valueFieldValue.ToString())] = value.ToString();
}
Я заменил как выше. Есть ли другой лучший способ для сравнения, чем этот?
9 ответов:
вы могли бы сделать его более читаемым и более эффективным:
string oldValue = valueFieldValue.ToString(); string newValue = value.ToString(); int index = listofelements.IndexOf(oldValue); if(index != -1) listofelements[index] = newValue;
Это спрашивает только один раз для индекса. Ваш подход использует
Contains
сначала нужно зациклить все элементы (в худшем случае), затем вы используетеIndexOf
который должен перечислить элементы снова .
используйте лямбда, чтобы найти индекс в списке и использовать этот индекс для замены элемента списка.
List<string> listOfStrings = new List<string> {"abc", "123", "ghi"}; listOfStrings[listOfStrings.FindIndex(ind=>ind.Equals("123"))] = "def";
вы обращаетесь к своему списку дважды, чтобы заменить один элемент. Я думаю, просто
for
петли должно быть достаточно:var key = valueFieldValue.ToString(); for (int i = 0; i < listofelements.Count; i++) { if (listofelements[i] == key) { listofelements[i] = value.ToString(); break; } }
почему бы не использовать методы расширения?
рассмотрим следующий код:
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}
- не дублировать код
- нет необходимости вводить длинные выражения linq
- нет необходимости в дополнительном использовании
исходный код:
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("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("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("source"); return source.Select(x => EqualityComparer<T>.Default.Equals(x, oldValue) ? newValue : x); } } }
первые два метода были добавлены для изменения объектов ссылочных типов на месте. Конечно, вы можете использовать только третий способ для всех типы.
П. С. Спасибо Майка!--20-->, я добавил метод ReplaceAll.
использовать
FindIndex
и лямбда, чтобы найти и заменить ваши значения: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
Я не знаю, если это лучше или нет, но вы можете использовать его также
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");
или, основываясь на предложении Rusian L., Если элемент, который вы ищете, может быть в списке более одного раза::
[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<string> listOfStrings = new List<string> {"abc", "123", "ghi"}; int index = listOfStrings.FindIndex(ind => ind.Equals("123")); if (index > -1) listOfStrings[index] = "def";
Я думаю, что лучше использовать ObservableCollection вместо List и преобразовать его в список, когда нам нужно его ранжировать. с observable collection вы можете удалить и добавить элемент в две строки, но вам нужно закодировать дюжину строк, чтобы получить эту функциональность с помощью списка. эта ссылка может дать четкое представление о ObservableCollection vs. List