#c#
#c#
Вопрос:
У меня есть массив значений int int[] ids
. У меня есть Datatable DataTable dt
, я хочу сохранить в массиве только те значения, которые есть в идентификаторах столбцов Datatable
Скажем int[] ids
, содержит [2,3,4,5]
dt
содержит [2,3,4,3,4]
— ids
здесь может повторяться
таким образом, вывод ids
будет иметь только [2,3,4]
Пожалуйста, предложите способы с помощью lambda или linq….
Я попробовал грубый способ, используя два foreachs.
Ответ №1:
используйте
int[] myIDs = (from d in dt.AsEnumerable() select d.Field<int>("id")).Intersect (ids).ToArray();
Для справки см.:
- http://msdn.microsoft.com/en-us/library/bb360891.aspx
- http://msdn.microsoft.com/en-us/library/system.data.datatableextensions.asenumerable.aspx
- http://msdn.microsoft.com/en-us/library/bb460136.aspx
- http://msdn.microsoft.com/en-us/library/x303t819.aspx
- http://msdn.microsoft.com/en-us/vcsharp/aa336746
- http://msdn.microsoft.com/en-us/vcsharp/aa336761.aspx#intersect1
Комментарии:
1. Оно должно быть
d["id"]
вместоdt["id"]
. На самом деле, я бы использовалd.Field<int>("id")
, чтобы гарантировать, что результирующий набор LINQ равен aIEnumerable<int>
вместоIEnumerable<object>
. О, и заменитьdt
наdt.AsEnumerable()
.2. Эй, Хайнци, можем ли мы аналогичным образом поступить и со словарем. словарь(объект, список <Дата-время>)!!
3. @PremanshuMishra вы тоже можете сделать что-то подобное
Dictionary
, но, пожалуйста, задайте новый вопрос и опишите конкретную цель, которую вы хотите достичь… пожалуйста, не забудьте проголосовать / отметить как принятый любой ответ, который помог…
Ответ №2:
Вам нужно создать новый массив. Массивы имеют фиксированный размер.
Если вам нужна структура данных, способная удалять элемент, вам нужен список. Обратите внимание, что операция удаления списка имеет наихудшую сложность O (n).
Однако для вашей конкретной проблемы я бы написал что-то вроде этого:
public int[] MyFunc(DataTable dt, int[] array)
{
Set<int> allowedsIds = new Set<int>();
Fill your set with ids you want to keep
int[] newArray = new int[inputArray.Length];
int newArrayCount = 0;
for (int i = 0; i < inputArray.Length; i)
{
if (allowedsIds.Contains(inputArray[i]))
{
newArray[newArrayCount ] = inputArray[i];
}
}
Array.Resize(ref newArray, newArrayCount);
return newArray;
}
Комментарии:
1. Почему удаление списка должно быть O (n ^ 2)?
Ответ №3:
Вам нужно пересечение 2 коллекций. Linq как метод пересечения для этого.
Из примеров Linq 101:
public void Linq50()
{
int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };
int[] numbersB = { 1, 3, 5, 7, 8 };
var commonNumbers = numbersA.Intersect(numbersB);
Console.WriteLine("Common numbers shared by both arrays:");
foreach (var n in commonNumbers)
{
Console.WriteLine(n);
}
}
Вы можете найти больше примеров здесь, в примерах Linq 101.
Ответ №4:
Используйте функцию Intersect:
var ids = new[] {2, 3, 4, 5};
var dt = new[] {2, 3, 4, 3, 4};
foreach (var id in ids.Intersect(dt))
{
}
Ответ №5:
Вы можете создать List<int> fromDB
и (циклически перебирать набор данных) заполнить его значениями столбцов ids.
Тогда вы могли бы использовать:
List<int> result = ids.Intersect(fromDB).ToList();