How to play items with a specific value for starting an array?

4

I have an array questions [] with the following properties:

perguntas[0] = { id:1; ordem: 3; inicio: 1 };
perguntas[1] = { id:2; ordem: 2; inicio: 0 }; 
perguntas[2] = { id:3; ordem: 1; inicio: 1 };

I would like to change them to order in the array according to the start property. Where 1 should come first than 0.

I already use a function to sort according to the order property, but this sort would be secondary, giving priority to items with the start property set to 1.

How can I do this?

The expected result would be:

perguntas[0] = { id:3; ordem: 1; inicio: 1 };
perguntas[1] = { id:1; ordem: 3; inicio: 1 }; 
perguntas[2] = { id:2; ordem: 2; inicio: 0 };
    
asked by anonymous 01.12.2014 / 14:30

3 answers

3

You can do this by following the MDN nominations . :

var ordenada = perguntas.sort(function (a, b) {
    if (a.inicio > b.inicio) return -1;
    if (a.inicio < b.inicio) return 1;
    return 0;
});

Example:

var perguntas = [];
perguntas[0] = {
    id: 1,
    ordem: 3,
    inicio: 1
};
perguntas[1] = {
    id: 2,
    ordem: 2,
    inicio: 0
};
perguntas[2] = {
    id: 3,
    ordem: 1,
    inicio: 1
};

var ordenada = perguntas.sort(function (a, b) {
    if (a.inicio > b.inicio) return -1;
    if (a.inicio < b.inicio) return 1;
    return 0;
});

alert(JSON.stringify(ordenada, null, 2));

Notice that you have a syntax error in the objects: it should be , to separate properties and not ;

    
01.12.2014 / 14:35
5

We already have good answers, but it follows a version that orders by several columns, using the traditional .sort , should anyone need in the future:

var perguntas = [];
perguntas[0] = { id:1, ordem: 3, inicio: 1 };
perguntas[1] = { id:2, ordem: 2, inicio: 0 }; 
perguntas[2] = { id:3, ordem: 1, inicio: 1 };
perguntas[4] = { id:3, ordem: 4, inicio: 1 };
perguntas[3] = { id:1, ordem: 4, inicio: 1 };
perguntas[5] = { id:3, ordem: 5, inicio: 1 };

// Aumente o "peso" a cada coluna extra
// sinal( ) * 8, * 16, * 32 etc...
var resultado = perguntas.sort(function (a, b) { return (
  sinal( a.inicio - b.inicio ) * 4 +
  sinal( a.ordem  - b.ordem  ) * 2 +
  sinal( a.id     - b.id     )
); } );

// Math.sign não é suportado em todos os browsers, segue implementação local:
function sinal( i ) {
  return ( i > 0 ) - ( i < 0 );
}

// Essa parte aqui é só pra exibir o resultado para conferirmos:
for ( i = 0; i < resultado.length; i++ ) {
  document.body.innerHTML += '<p>' + JSON.stringify( resultado[i] ) + '</p>';
}

In this case, it is enough by "weights" in the desired items, so that it weighs more the difference of the main column, but if it ties, weighs that of the second column, and so on.

So we use powers of 2 in the weights (1, 2, 4, 8, 16) to ensure that the weights of the summed lower columns never exceed a higher column.

    
01.12.2014 / 18:21
3

You can create a new sort function that makes use of the first one:

perguntas = perguntas.sort(function(a, b) {
    return a.inicio > b.inicio ? -1 : b.inicio > a.inicio ? 1 : comparadorAntigo(a, b);
});

Or, if you have access to a stable

strong> (it seems to me that% default JavaScript does not enforce this restriction, so different browsers implement this inconsistently ) you can sort first by the secondary characteristic, then by the primary one. Example using underscore.js:

var perguntas = [];
perguntas[0] = { id:1, ordem: 3, inicio: 1 };
perguntas[1] = { id:2, ordem: 2, inicio: 0 }; 
perguntas[2] = { id:3, ordem: 1, inicio: 1 };

perguntas = _.sortBy(perguntas, "ordem"); // Ou seja qual for seu critério secundário
perguntas = _.sortBy(perguntas, function(x) { return -x.inicio; });

document.getElementsByTagName("body")[0].innerHTML = JSON.stringify(perguntas);
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
    
01.12.2014 / 17:11