Autor Zpráva
DarkMeni
Profil
Zdravím, je možné metodou Array.sort nějak řadit podle více priorit?
Zkoušel jsem:
pole.sort(function(a, b){
  return (a[1] + a[2] + a[3]) - (b[1] + b[2] + b[3]);
});
Ale to nedělalo přesně to, co jsem chtěl:
//Struktura pole
var pole = [
  [[/*prvek, který nemá mít pro řazení žádný význam*/0, 1, 0, -1, 0, 1], priorita3, priorita2, priorita1]
]
//Takže z:
[
  [[0, 1, 2, -1, 0, 3],   0, 1, 2],
  [[0, -1, 2, -1, 0, 3],  0, 2, 2],
  [[0, 1, 2, 0, 0, -1],   1, 1, 1],
  [[0, 1, 2, -1, -1, -1], 1, 3, 1],
  [[0, 1, 2, -1, 0, 3],   11, 1, 1],
  [[0, 1, 2, 0, 0, 3],     2, 0, 0]
]
//Chci dostat:
[
  [[0, 1, 2, 0, 0, 3],    2,  0, 0]
  [[0, 1, 2, 0, 0, -1],   1,  1, 1],
  [[0, 1, 2, -1, 0, 3],   3,  1, 1],
  [[0, 1, 2, -1, 0, 3],   12, 1, 1],
  [[0, 1, 2, -1, -1, -1], 1,  3, 1],
  [[0, 1, 2, -1, 0, 3],   0,  1, 2],
  [[0, -1, 2, -1, 0, 3],  0,  2, 2],
]
Kdyby jsem použil jen pole.sort(); s trochu jinak seřazenou strukturou ([priorita1, priorita2, priorita3, [prvky]]), tak se v případě jednočíselných priorit seřadí správně, ale když se objeví hodnoty priority s více čísly, tak se seřadí podle prvního čísla v hodnotě priority, takže vlastně:
var vysledek = [
  [0, 0, 2, [0, 1, 2, 0, 0, 3]],
  [1, 1, 1, [0, 1, 2, 0, 0, -1]],
  [1, 1, 12, [0, 1, 2, -1, 0, 3]],
  [1, 1, 3, [0, 1, 2, -1, 0, 3]],
  [1, 3, 1, [0, 1, 2, -1, -1, -1]],
  [2, 1, 0, [0, 1, 2, -1, 0, 3]],
  [2, 2, 0, [0, -1, 2, -1, 0, 3]]
]
Je možné teda nějak napsat vlastní řadící funkci pro Array.sort, aby to řadilo podle 3 priorit, nebo je jediná možnost to ukládat do asociativních polí a potom procházet a řadit podle toho, jak je to uložené v asociatovním poli s těmi prioritami přes asi o dost pomalejší for in?
Darker
Profil
Promiň, několikrát jsem si to přečetl a nedochází mi jak že to chceš řadit. Jsem si ale jistí, že na to jde napsat správný callback.
DarkMeni
Profil
Mám několik proměnných, které mají svojí důležitost, a podle nich:
Když má nejdůležitější proměnná a vyšší hodnotu než b, pak se má dát na menší index a;
Když má nejdůležitější proměnná a stejnou hodnotu jako b, pak se má testovat druhá nejdůležitější, a podle toho se rozhodnout, který bude mít menší index;
Když má druhá nejdůležitější proměnná a taky stejnou hodnotu jako b, pak se mají porovnat ty třetí nejdůležitější... kdyby jich bylo víc tak pak čtvrý, pátý atd...
Nakonec jsem to s matematickým řešením vzdal a napsal to normálně v podmínkách - i když si myslím, že by to nějak matematicky a efektivněji šlo taky vyřešit.
var pole = [
  [[prvky_na_řazení], třetí_priorita, druhá_priorita, nejdůležitější_priorita]//Struktura pole
];
pole.sort(
    function(a, b){
        if(a[3] < b[3]){
            return -1;
        }else if(a[3] == b[3] && a[2] <= b[2]){
            if(a[2] == b[2] && a[1] >= b[1]){
                return 1;
            }
            return -1;
        }
        return 1;
    }
);
Darker
Profil
Pro libovolný počet úrovní důležitosti:
function callback(a,b) {
  for(var i=0; i<a.length&&i<b.length; i++){
      if(a[i]!=b[i])
        return a[i]-b[i];
  }
  return 0;
}
Pokud máš úrovně tři, dej tam i<3. Význam toho vnořeného pole nechápu. Pro příště ti doporučuji důležité hodnoty v poli nějak zvýraznit (tag B).
DarkMeni
Profil
To je ono, díky!
To vnořené pole (prvek) je to, ke kterému se vztahují ty priority, a které chci mít v poli pole seřazené.
Při vytváření toho pole mám už ty priority k dispozici, tak aby jsem to při procházení pole nemusel znova přepočítávat, tak to řešim takto, navíc ta 3 priorita by se z obsahu toho pole stejně nedala zjisit.
Ale tvůj callback to řeší skoro přesně tak, jak jsem to chtěl, jen nějak otočit pořadí (nejdůležitější priorita se do pole přidá jako poslední) a vynechat porovnávání toho vnořeného pole, kdyby se všechny hodnoty priorit shodovaly, takže asi nějak:
function callback(a, b){
  for(var i = a['length'] - 1; i > 1; i--){//Nemělo by se stát že a['length'] bude jiný než b['length']
    if(a[i] != b[i]){
      return a[i] - b[i];
    }
  }
  return 1;//U 0 jsem někde viděl že se to ve starších prohlížečích může chovat nepředpovídatelně nebo tak něco
}
Takže ještě jednou díky.
Darker
Profil
DarkMeni:
U 0 jsem někde viděl že se to ve starších prohlížečích může chovat nepředpovídatelně nebo tak něco
Pokud se prvky rovnají, vrať nulu. Proč myslíš, že základní konstrukce je:
return a-b;
a ne
return a==b?1:a-b;
peta
Profil
Column sort
http://peter-mlich.wz.cz/web/js/pr/index.htm#arraysort
Ale nevim, co to udela s tim pole v poli :)

var m, n, orderby;
// Id, Cena, Nazev, Kategorie, Popis
m = [
[1, "130 Kc", "Podlozky", "Zelezne vyrobky", "Tvrde podlozky"],
[2, "130 Kc", "Hrebiky" , "Zelezne vyrobky", "Pevne hrebiky" ],
[3, "130 Kc", "Pilka"   , "Naradi"         , "Ostra pilka"   ],
[4, "200 Kc", "Kladivo" , "Naradi"         , "Velke kladivo" ]
];
n = [
[1, "130 Kc", "Podlozky", "Zelezne vyrobky", "Tvrde podlozky"],
[2, "130 Kc", "Hrebiky" , "Zelezne vyrobky", "Pevne hrebiky" ],
[3, "130 Kc", "Pilka"   , "Naradi"         , "Ostra pilka"   ],
[4, "200 Kc", "Kladivo" , "Naradi"         , "Velke kladivo" ]
];
// Kategorie, Cena, Nazev, Popis
orderby = {3:{}, 1:{order:'desc',func:'strnum'}, 2:{}, 4:{}};
n = n.sort(function(a,b)
    {
    var i,func,order,result,column,f,o;
    func = {
        'str': function(a,b){if (a < b) {return -1;}; if (a > b) {return 1;}; if (a == b) {return 0;}; return false;},
        'strnum': function(a,b){var f = function(s){return ('' + s).replace(/[^.0-9]/g,"") * 1;}; return f(a) - f(b);}
        };
    order = {
        'asc': function(q){return q;},
        'desc': function(q){return -q;}
        };
    result = 0;
    for (i in orderby)
        {
        column = orderby[i];
        f = typeof(column)=='object' && column.func  ? column.func  : 'str';
        o = typeof(column)=='object' && column.order ? column.order : 'asc';
        result = order[o](func[f](a[i],b[i]));
        if (result>0)
            {
            return result;
            }
        }
    return result;
    }
);
// vypis vysledku
for (i=0;i<m.length;i++)
    {
    m[i] = "[" + m[i].join(", ") + "]";
    }
for (i=0;i<n.length;i++)
    {
    n[i] = "[" + n[i].join(", ") + "]";
    }
document.write("inp = [\n" + m.join(",\n")+ "\n];\nout = [\n" + n.join(",\n")+ "\n];");

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: