2011-08-07 2 views
2

j'ai un tableau en tant que tel:Trie un tableau d'avoir des éléments spécifiques d'abord dans le tableau

[{flag: true, other: 1}, 
{flag: true, other: 2}, 
{flag: false, other: 3}, 
{flag: true, other: 4}, 
{flag: true, other: 5}, 
{flag: true, other: 6}, 
{flag: false, other: 7}] 

Je veux avoir ceci:

[{flag: false, other: 3}, 
{flag: false, other: 7}, 
{flag: true, other: 1}, 
{flag: true, other: 2}, 
{flag: true, other: 4}, 
{flag: true, other: 5}, 
{flag: true, other: 6}] 

Fondamentalement, je veux que si array[2].flag === false (ou toute autre valeur que je choisis) l'élément correspondant est placé en premier dans le tableau, mais après les éléments correspondants précédents. Les éléments qui ne correspondent pas restent dans le même ordre qu'ils étaient à l'origine.

L'ordre d'apparition est important.

Comment faire de mieux en JavaScript?

+0

Merci pour le modifier pimvdb – DLeonardi

+0

Qu'en est-il de l'ordre des éléments avec 'flag' de' false', relati l'un à l'autre? – amn

+0

@amn: L'ordre dans lequel ils sont "préfixés" au tableau doit être l'ordre dans lequel ils ont été rencontrés dans le tableau original. – DLeonardi

Répondre

3

Cela ne fait le tri. Vous pouvez juste boucle à travers le réseau deux fois et construire un nouveau tableau:

var result = []; 
for (var i = 0; i < arr.length; i++) { 
    if (arr[i].flag === false) { 
    result.push(arr[i]); 
    } 
} 
for (var i = 0; i < arr.length; i++) { 
    if (!arr[i].flag === false) { 
    result.push(arr[i]); 
    } 
} 

Vous pouvez aussi le faire avec deux tableaux de résultats et une boucle, et concaténer les résultats:

var result1 = [], result2 = []; 
for (var i = 0; i < arr.length; i++) { 
    if (arr[i].flag === false) { 
    result1.push(arr[i]); 
    } else { 
    result2.push(arr[i]); 
    } 
} 
var result = result1.concat(result2); 
8

Ecrire une fonction de tri personnalisé et utilise le drapeau pour augmenter la priorité:

array.sort(function(a,b) { 
    if (!a['flag'] && b['flag']) 
    return 1; 
    if (a['flag'] && !b['flag']) 
    return -1; 
    return a['other'] - b['other'] 
}); 
-1
arr = arr.sort(function(a, b) { // sort the array using a custom function, 
           // which is called a number of times to 
           // determine the new order. a and b are two 
           // elements to compare. JavaScript uses the 
           // return value to determine the new order: 
           // 1 - a should come later than b 
           // -1 - a should come earlier than b 
           // 0 - they should stay in their current order 
    return a.flag === true && b.flag === false 
      ? 1 // if a is true and b is false a should come later on 
      : a.flag === false && b.flag === true 
       ? -1 // if a is false and b is true a should come earlier 
       : a.other > b.other 
        ? 1 // if a.other > b.other, a must come later on 
        : a.other < b.other 
        ? -1 // if a.other < b.other, a must come earlier 
        : 0; // otherwise they are equal, so they have no order difference 
}); 
0

Puisque vous voulez sélectionnez certains éléments du tableau, mais gardez-les dans leur ordre d'origine, vous voulez la méthode filter(). Cette fonction est un extension to the standard, vous devrez peut-être utiliser la cale fournie à cette page selon les navigateurs que vous prenez en charge.

(Quand je lis votre question, je pensais que vous vouliez trier en fonction du drapeau, puis en fonction de la valeur, car vous pouvez utiliser la méthode intégrée sort().)

var input = [{flag: true, other: 1}, 
      {flag: true, other: 2}, 
      {flag: false, other: 3}, 
      {flag: true, other: 4}, 
      {flag: true, other: 5}, 
      {flag: true, other: 6}, 
      {flag: false, other: 7}] 
var false_items = input.filter(
     function(val, idx, arr) { 
      return (val["flag"] == false); 
     }); 
var true_items = input.filter(
     function(val, idx, arr) { 
      return (val["flag"] == true); 
     }); 

var sorted = false_items.concat(true_items); 
1

I pense que c'est un peu simple. Parce que javascript traite vrai 1 et faux que 0, vous pouvez les utiliser pour créer un comparateur comme celui-ci,

var comp = function(a,b){ 
    return a.flag*1 - b.flag*1; 
} 

et vous pouvez utiliser ce comparateur pour trier le tableau

var arr = [{flag: true, other: 1}, 
     {flag: true, other: 2}, 
     {flag: false, other: 3}, 
     {flag: true, other: 4}, 
     {flag: true, other: 5}, 
     {flag: true, other: 6}, 
     {flag: false, other: 7}]; 
arr.sort(comp); 
6

ES6 rend cette relativement simple dans une opération reduce:

const arr = [ 
{flag: true, other: 1}, 
{flag: true, other: 2}, 
{flag: false, other: 3}, 
{flag: true, other: 4}, 
{flag: true, other: 5}, 
{flag: true, other: 6}, 
{flag: false, other: 7}]; 

const sortedArr = arr.reduce((acc, element) => { 
    if (element.flag === false) { 
    return [element, ...acc]; 
    } 
    return [...acc, element]; 
}, []); 
+1

n'est pas la méthode de réduction manquant un second argument (initialValue) ?, dans ce cas un tableau vide. Cela ne devrait-il pas être? '' 'arr.reduce ((acc, element) => {}, [])' '' – ivanji

+0

Oui, vous avez raison. Sans initialValue fourni après la fonction de rappel, 'reduce' utilisera le premier élément du tableau comme valeur initiale par rapport à un objet tableau vide. J'ai mis à jour mon bloc de code pour refléter la signature de la méthode. – felguerez

Questions connexes