Рейтинг:
7
Thomas Daniels
Решение 1 обеспечивает самый простой способ сделать это. Однако если вам действительно нужно иметь одно поле имени, есть способ его сортировки:
dt.AsEnumerable().OrderBy(x => (x.ItemArray[0] as string).Split(' ')[1]).CopyToDataTable(); // where 'dt' is your DataTable
AsEnumerable
возвращает
EnumerableRowCollection<DataRow>
, по которому вы можете позвонить
OrderBy
с лямбда-выражением, которое говорит использовать второе слово имени. Это возвращает
OrderedEnumerableRowCollection<DataRow>
и вы можете позвонить
CopyToDataTable
чтобы преобразовать эту коллекцию в новую
DataTable
.
Kingshuk_SP
один вопрос.
can you explain the use of "Split(' ')[1]" in the query please ???
Kingshuk_SP
да, я получил это для первого места, мы получим фамилию и сортировку. хорошо.
Но если имя столбца, как:
Мэри Сью Ван Пелт
Роза Ван Джульетта
в таком случае, как я могу запустить цикл ?
Thomas Daniels
Что вы здесь считаете "фамилией"? Только последняя часть? Или все, кроме первой части?
Kingshuk_SP
yeah only last part.
like in case of the below name:
Mary Sue Van Pelt
"Pelt" would be the last name
Kingshuk_SP
спасибо, ребята. Я нашел решение:
код будет таким:
dt = dt.AsEnumerable().OrderBy(x => (x.ItemArray[0] as string).Split(' ')[(x.ItemArray[0]).ToString().Split(' ').Length - 1]).CopyToDataTable();
Thomas Daniels
Если вы используете LINQ (using System.Linq;
), вы также можете использовать .Last
метод расширения для облегчения чтения вашего кода:
.Split(' ').Last()
Kingshuk_SP
спасибо @ProgramFOX
это уменьшило мой код... ура. :)
Thomas Daniels
Пожалуйста!
Kingshuk_SP
мне нужно еще кое-что. У меня есть datatable, как показано ниже:
Name Department
John Alter D01
Prakash Kiran D01
Steffy Cold D01
Julia Roberts D02
Candy Mitchel D02
Monika Diesel D03
Я хочу, чтобы это было как ниже:
Name Department
John Alter D01
Prakash Kiran
Steffy Cold
Julia Roberts D02
Candy Mitchel
Monika Diesel D03
когда его заказывает отдел, он не должен повторяться для одного и того же отдела.
Но строка должна быть там, только если в следующей строке под столбцом отдела есть такое же значение, которое должно быть пустым
Thomas Daniels
Для этого нет однострочного решения, но это работает (Примечание: чтобы это сработало, DataTable уже должен быть отсортирован)
DataTable newDt = dt.Clone(); // clones the structure, not the data
for (int i = 0; i < dt.Rows.Count; i++)
{
DataRow newRow = newDt.NewRow();
newRow["Name"] = dt.Rows[i]["Name"];
int originalIndex = dt.AsEnumerable().ToList().FindIndex(x => x["Department"] == dt.Rows[i]["Department"]);
if (originalIndex < i)
{
newRow["Department"] = "";
}
else
{
newRow["Department"] = dt.Rows[i]["Department"];
}
newDt.Rows.Add(newRow);
}
Kingshuk_SP
in this case the condition if (originalIndex < i) always is false and thus not removing the duplicate names.
i think we should go for a counter or flag concept
Kingshuk_SP
in this case the condition if (originalIndex < i) always is false and thus not removing the duplicate names.
Thomas Daniels
Для меня это сработало. originalIndex - это первое вхождение определенного отдела, поэтому "originalIndex < i" будет истинным, если имя отдела будет использовано позже.
Kingshuk_SP
для меня это не работает, потому что всегда значение originalIndex равно значению i.
Я отладил и все равно его же. :(
Thomas Daniels
Тогда, боюсь, я ничем не могу помочь.
Kingshuk_SP
ok. but when I am debugging , i saw...
every time the loop runs, as the "i" value increments, the originalIndex value also increments.. always their value is same. that's y its not going to be true anytime.
int originalIndex = dt.AsEnumerable().ToList().FindIndex(x => x["Department"] == dt.Rows[i]["Department"]);
here originalIndex value is dependent on "i" everytime
so it will find the index of that row according to i value right.
so as an example, when i == 0 , then it will find the index of department corresponds to 0th row and so on....
then how it is coming different in your case, I am not getting really. :)
if you don't mind can you please re-check if you have made any small code changes inside this please
Thomas Daniels
dt.Rows[i]["Department"]
просто возвращает отдел строки, которую вы копируете в newDt, так что это будет "D01" как для первой, так и для второй строки.
Это прекрасно работает для меня; единственное, что я вижу, что можно было бы изменить, - это замена '==' в этой строке на вызов. Equals:
int originalIndex = dt.AsEnumerable().ToList().FindIndex(x => x["Department"].Equals(dt.Rows[i]["Department"]));
Kingshuk_SP
Большое спасибо. Это делается с помощью Equal. овации. :)