primeng datatable sort table на два столбца одновременно [дубликат]

Я также пытался работать с подобной SQL-IN-вещью - запросом на модель данных сущности. Мой подход - строковый построитель для создания большого OR-выражения. Это ужасно уродливо, но я боюсь, что это единственный способ пойти прямо сейчас.

Теперь хорошо, это выглядит так:

Queue<Guid> productIds = new Queue<Guid>(Products.Select(p => p.Key));
if(productIds.Count > 0)
{
    StringBuilder sb = new StringBuilder();
    sb.AppendFormat("{0}.ProductId = Guid\'{1}\'", entities.Products.Name, productIds.Dequeue());
    while(productIds.Count > 0)
    {
        sb.AppendFormat(" OR {0}.ProductId = Guid\'{1}\'",
          entities.Products.Name, productIds.Dequeue());
    }
}

Работа с GUID в этом контексте: Как вы можете видеть выше, всегда есть слово «GUID» перед GUID ifself в фрагментах строки запроса. Если вы не добавите это, ObjectQuery<T>.Where выдает следующее исключение:

Типы аргументов «Edm.Guid» и «Edm.String» несовместимы для этой операции., Near equals expression , строка 6, столбец 14.

Обнаружено это в форумах MSDN, может быть полезно иметь в виду.

Matthias

... с нетерпением жду следующей версии .NET и Entity Framework, когда все станет лучше. :)

44
задан Chris Eberle 25 May 2011 в 20:45
поделиться

12 ответов

grouperArray.sort(function (a, b) {
    var aSize = a.gsize;
    var bSize = b.gsize;
    var aLow = a.glow;
    var bLow = b.glow;
    console.log(aLow + " | " + bLow);

    if(aSize == bSize)
    {
        return (aLow < bLow) ? -1 : (aLow > bLow) ? 1 : 0;
    }
    else
    {
        return (aSize < bSize) ? -1 : 1;
    }
});
62
ответ дан Chris Eberle 19 August 2018 в 13:52
поделиться
  • 1
    Спасибо. Я действительно боролся, как сортировать по нескольким полям. – Maximus 9 November 2017 в 00:50
grouperArray.sort(function (a, b) {   
    return a.gsize - b.gsize || a.glow - b.glow;
});

более короткая версия

57
ответ дан anmorozov23 19 August 2018 в 13:52
поделиться

Вот реализация, которая использует рекурсию для сортировки по любому числу полей сортировки от 1 до бесконечного. Вы передаете ему массив результатов, который представляет собой массив объектов результатов для сортировки, и массив sorts, который представляет собой массив объектов сортировки, определяющих сортировку. У каждого объекта сортировки должен быть ключ «выбрать» для имени ключа, которое он сортирует, и ключ «порядок», который является строкой, обозначающей «восходящий» или «нисходящий».

sortMultiCompare = (a, b, sorts) => {
    let select = sorts[0].select
    let order = sorts[0].order
    if (a[select] < b[select]) {
        return order == 'ascending' ? -1 : 1
    } 
    if (a[select] > b[select]) {
        return order == 'ascending' ? 1 : -1
    }
    if(sorts.length > 1) {
        let remainingSorts = sorts.slice(1)
        return this.sortMultiCompare(a, b, remainingSorts)
    }
    return 0
}

sortResults = (results, sorts) => {
    return results.sort((a, b) => {
        return this.sortMultiCompare(a, b, sorts)
    })
}

// example inputs
const results = [
    {
        "LastName": "Doe",
        "FirstName": "John",
        "MiddleName": "Bill"
    },
    {
        "LastName": "Doe",
        "FirstName": "Jane",
        "MiddleName": "Bill"
    },
    {
        "LastName": "Johnson",
        "FirstName": "Kevin",
        "MiddleName": "Bill"
    }
]

const sorts = [
    {
        "select": "LastName",
        "order": "ascending"
    },
    {
        "select": "FirstName",
        "order": "ascending"
    },
    {
        "select": "MiddleName",
        "order": "ascending"
    }    
]

// call the function like this:
let sortedResults = sortResults(results, sorts)
1
ответ дан Benjamin Portman 19 August 2018 в 13:52
поделиться

Это то, что я использую

function sort(a, b) {
    var _a = "".concat(a.size, a.glow);
    var _b = "".concat(b.size, b.glow);
    return _a < _b;
}

, разделив два элемента как строку, и они будут отсортированы по строковому значению. Если вы хотите, вы можете обернуть _a и _b с помощью parseInt, чтобы сравнить их как числа, если вы знаете, что они будут численными.

0
ответ дан blockloop 19 August 2018 в 13:52
поделиться
grouperArray.sort(
  function(a,b){return a.gsize == b.gsize ? a.glow - b.glow : a.gsize - b.gsize}
);
0
ответ дан ic3b3rg 19 August 2018 в 13:52
поделиться

Я ожидаю, что ваш троичный оператор ((aSize < bSize) ? -1 : (aSize > bSize) ? 1 : 0;) вас смутит. Вы должны проверить ссылку, чтобы лучше понять ее.

До тех пор, вот ваш код выдувается в полноэкранном режиме if / else.

grouperArray.sort(function (a, b) {
    if (a.gsize < b.gsize)
    {
        return -1;
    }
    else if (a.gsize > b.gsize)
    {
        return 1;
    }
    else
    {
        if (a.glow < b.glow)
        {
            return -1;
        }
        else if (a.glow > b.glow)
        {
            return 1;
        }
        return 0;
    }
});
6
ответ дан John Green 19 August 2018 в 13:52
поделиться

Я понимаю, что это было спрошено некоторое время назад, но я думал, что добавлю свое решение.

Эта функция динамически генерирует методы сортировки. просто укажите каждое сортируемое дочернее свойство, добавленное +/-, чтобы указать восходящий или нисходящий порядок. Супер можно использовать повторно, и ему не нужно ничего знать о структуре данных, которую вы собрали вместе.

function getSortMethod(){
    var _args = Array.prototype.slice.call(arguments);
    return function(a, b){
        for(var x in _args){
            var ax = a[_args[x].substring(1)];
            var bx = b[_args[x].substring(1)];
            var cx;

            ax = typeof ax == "string" ? ax.toLowerCase() : ax / 1;
            bx = typeof bx == "string" ? bx.toLowerCase() : bx / 1;

            if(_args[x].substring(0,1) == "-"){cx = ax; ax = bx; bx = cx;}
            if(ax != bx){return ax < bx ? -1 : 1;}
        }
    }
}

пример использования:

items.sort (getSortMethod ('- price', '+ priority', ' + name '));

это сначала сортировало бы items с наименьшим price, причем привязки переходили к элементу с наивысшим priority. дальнейшие связи нарушаются элементом name

, где элементы представляют собой массив, подобный:

var items = [
    { name: "z - test item", price: "99.99", priority: 0, reviews: 309, rating: 2 },
    { name: "z - test item", price: "1.99", priority: 0, reviews: 11, rating: 0.5 },
    { name: "y - test item", price: "99.99", priority: 1, reviews: 99, rating: 1 },
    { name: "y - test item", price: "0", priority: 1, reviews: 394, rating: 3.5 },
    { name: "x - test item", price: "0", priority: 2, reviews: 249, rating: 0.5 } ...
];

live demo: http://gregtaff.com/misc/ multi_field_sort /

EDIT: Исправлена ​​проблема с Chrome.

6
ответ дан nihlton 19 August 2018 в 13:52
поделиться
grouperArray.sort(function (a, b) {
  var aSize = a.gsize;
  var bSize = b.gsize;
  var aLow = a.glow;
  var bLow = b.glow;
  console.log(aLow + " | " + bLow);      
  return (aSize < bSize) ? -1 : (aSize > bSize) ? 1 : ( (aLow < bLow ) ? -1 : (aLow > bLow ) ? 1 : 0 );
});
3
ответ дан silex 19 August 2018 в 13:52
поделиться

Вот реализация для тех, кто может захотеть что-то более общее, которое будет работать с любым количеством полей.

Array.prototype.sortBy = function (propertyName, sortDirection) {

    var sortArguments = arguments;
    this.sort(function (objA, objB) {

        var result = 0;
        for (var argIndex = 0; argIndex < sortArguments.length && result === 0; argIndex += 2) {

            var propertyName = sortArguments[argIndex];
            result = (objA[propertyName] < objB[propertyName]) ? -1 : (objA[propertyName] > objB[propertyName]) ? 1 : 0;

            //Reverse if sort order is false (DESC)
            result *= !sortArguments[argIndex + 1] ? 1 : -1;
        }
        return result;
    });

}

В принципе, вы можете указать любое количество свойств / направление сортировки:

var arr = [{
  LastName: "Doe",
  FirstName: "John",
  Age: 28
}, {
  LastName: "Doe",
  FirstName: "Jane",
  Age: 28
}, {
  LastName: "Foo",
  FirstName: "John",
  Age: 30
}];

arr.sortBy("LastName", true, "FirstName", true, "Age", false);
//Will return Jane Doe / John Doe / John Foo

arr.sortBy("Age", false, "LastName", true, "FirstName", false);
//Will return John Foo / John Doe / Jane Doe
2
ответ дан The_Black_Smurf 19 August 2018 в 13:52
поделиться
grouperArray.sort(function (a, b) {
     var aSize = a.gsize;     
     var bSize = b.gsize;     
     var aLow = a.glow;
     var bLow = b.glow;
     console.log(aLow + " | " + bLow);
     return (aSize < bSize) ? -1 : (aSize > bSize) ? 1 : (aLow < bLow) ? -1 : (aLow > bLow) ? 1 : 0); }); 
3
ответ дан Tim Williams 19 August 2018 в 13:52
поделиться
grouperArray.sort((a, b) => a.gsize - b.gsize || a.glow - b.glow);

Даже более короткая версия с использованием синтаксиса стрелок!

2
ответ дан Vinorth 19 August 2018 в 13:52
поделиться
grouperArray.sort(function (a, b) {
    var aSize = a.gsize;
    var bSize = b.gsize;
    if (aSize !== aSize)
        return aSize - bSize;
    return a.glow - b.glow;
});

не проверен, но я думаю, что он должен работать.

0
ответ дан Xander 19 August 2018 в 13:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: