JavaScript verschiebt ein Element eines Arrays nach vorne

75

Ich möchte überprüfen, ob ein Array enthält "role". Wenn dies der Fall ist, möchte ich das "role"an die Vorderseite des Arrays verschieben.

var data= ["email","role","type","name"];
if ("role" in data) data.remove(data.indexOf("role")); data.unshift("role")
data;

Hier habe ich das Ergebnis:

["role", "email", "role", "type", "name"]

Wie kann ich das beheben?

user2634156
quelle
Mögliches Duplikat von Element aus Array nach Wert entfernen
Miklos Aubert
2
@jraede: Natürlich ist es gültig?
Bergi
Was ist das für eine removeMethode? Verwenden Sie Prototype.js oder ähnliches?
Bergi
if('role' in data)und data.remove()?
jraede

Antworten:

75

Sie können das Array sortieren und angeben, dass der Wert "role"vor allen anderen Werten steht und dass alle anderen Werte gleich sind:

var first = "role";
data.sort(function(x,y){ return x == first ? -1 : y == first ? 1 : 0; });

Demo: http://jsfiddle.net/Guffa/7ST24/

Guffa
quelle
15
Das könnte die Reihenfolge der anderen Elemente ändern, sortist jedoch nicht stabil.
Bergi
@Bergi: Guter Punkt, das ist etwas zu beachten. Das ist abhängig von der Implementierung, und es scheint , die meisten Browser eine stabile haben sort: stackoverflow.com/questions/3026281/...
Guffa
4
Funktioniert, aber das Verschachteln von Tertiärs macht es ziemlich schwer, Code zu verstehen
Waltari
Gibt es eine Möglichkeit, die verbleibenden Elemente außer "Rolle" zu sortieren
Jeya Suriya Muthumari
Wenn Sie diesen JS-Geigen-Link googeln, werden Sie feststellen, dass er im Internet sehr beliebt ist. Danke, das hat mir wirklich geholfen.
Nikita Fuchs
65

Die sauberste Lösung in ES6 meiner Meinung nach:

let data = ["email","role","type","name"];
data = data.filter(item => item !== "role");
data.unshift("role");
Skylar Brown
quelle
56

Mein erster Gedanke wäre:

var data= ["email","role","type","name"];

// if it's not there, or is already the first element (of index 0)
// then there's no point going further:
if (data.indexOf('role') > 0) {
    // find the current index of 'role':
    var index = data.indexOf('role');
    // using splice to remove elements from the array, starting at
    // the identified index, and affecting 1 element(s):
    data.splice(index,1);
    // putting the 'role' string back in the array:
    data.unshift('role');
}

console.log(data);

Um zu überarbeiten und ein wenig aufzuräumen:

if (data.indexOf('role') > 0) {
    data.splice(data.indexOf('role'), 1);
    data.unshift('role');
}

Verweise:

David sagt, Monica wieder einsetzen
quelle
10
Ich denke, wir können dies ein wenig verbessern, indem wir die Array.indexOf()Funktion nicht zweimal verwenden müssen, da dies bedeutet, dass das gesamte Array zweimal durchsucht wird. `` `const roleIndex = data.indexOf ('role'); if (roleIndex> 0) {data.splice (roleIndex, 1); data.unshift ('Rolle'); } `` `
Ariella
1
Es ist vernünftiger als zu sortieren.
MajidTaheri
data.spliceGibt den gerade entfernten Teil zurück, den Sie sofort zum Einfügen verwenden können, sodass er 1 Zeile statt 2 ist, und macht ihn auch für kompliziertere Fälle wie für eine Reihe von Objekten nützlich:data.unshift(data.splice(roleIndex, 1)[0])
Maxim Georgievskiy
37
let data = [0, 1, 2, 3, 4, 5];
let index = 3;
data.unshift(data.splice(index, 1)[0]);
// data = [3, 0, 1, 2, 4, 5]
sdfsdf
quelle
4
Dies ist bei weitem die beste Antwort, da sie sich eher auf einen Index als auf einen Wert stützt. So ist es sinnvoll für diejenigen , beide wollen auf einen Index verlassen, und diejenigen , die auf einen Wert setzen (die einfach ersetzen kann indexmit data.findIndex(value)).
Goodvibration
17

Wenn Sie das vorhandene Array nicht ändern möchten, können Sie mithilfe der ES6-Destrukturierung mit der Filtermethode eine neue Kopie erstellen und dabei die Reihenfolge der anderen Elemente beibehalten.

const data = ["email", "role", "type", "name"];
const newData = ['role', ...data.filter(item => item !== 'role')];
Tandroid
quelle
12

Hier ist eine unveränderliche Lösung, falls erforderlich:

      const newData = [
          data.find(item => item === 'role'),
          ...data.filter(item => item !== 'role'),
        ],
Maldoror
quelle
Was ist, wenn es kein Element gibt, das gleich "Rolle" wäre? In diesem Fall hätten Sie undefinedals erstes Element des Arrays.
Jan Jůna
Sie haben Recht, in diesem Beitrag verwendet er: if ("role" in data)bevor er "Rolle" auf den ersten Platz schiebt. Meine Antwort war nicht gründlich, aber sie bittet implizit um eine vorherige Überprüfung (ansonsten aktualisieren wir das Array nicht)
Maldoror
5

Wenn Sie ein Array von Objekten haben, können Sie den Startindex mit Splice und Push verschieben. Splice ersetzt das ursprüngliche Array durch den Teil des Arrays, beginnend mit dem gewünschten Index, und gibt den Teil zurück, den es entfernt (das Material vor dem Index), den Sie verschieben.

let friends = [{
    id: 1,
    name: "Sam",
  },
  {
    id: 2,
    name: "Steven",
  },
  {
    id: 3,
    name: "Tom",
  },
  {
    id: 4,
    name: "Nora",
  },
  {
    id: 5,
    name: "Jessy",
  }
];

const tomsIndex = friends.findIndex(friend => friend.name == 'Tom');
friends.push(...friends.splice(0, tomsIndex));

console.log(friends);

Tamo Maes
quelle
4

Um zu überprüfen, ob ein Element in einem Array vorhanden ist, sollten Sie es .includes()anstelle von verwenden in(wie hier bereits erwähnt, ingilt für Eigenschaften in Objekten).

Diese Funktion macht das, wonach Sie suchen: (Entfernt das Objekt aus der Position, in der es sich befindet, und liest es vor)

   data = ["email","role","type","name"];
   moveToFirst("role", data)
    
   function moveToFirst(s, r){
      if (r.includes(s)){
        r.splice(r.indexOf(s),1);
        r.unshift(s);
      } 
    }
    
    console.log(data)

JPR
quelle
3

Ich würde mit dieser ES6-Lösung gehen. Es mutiert nicht das ursprüngliche Array (wenn man bedenkt, dass es nicht verschachtelt ist), durchläuft das Array (Filter) nicht und Sie sind nicht nur auf den 0. Index beschränkt, um das Array-Element zu verschieben.

const moveArrayItem = (array, fromIndex, toIndex) => {
    const arr = [...array];
    arr.splice(toIndex, 0, ...arr.splice(fromIndex, 1));
    return arr;
}


const arr = ["a", "b", "c", "d", "e", "f", "g"];
console.log(moveArrayItem(arr, 4, 0))
// [ 'e', 'a', 'b', 'c', 'd', 'f', 'g' ]
Rajender Joshi
quelle
2
  1. Beim inOperator geht es um Eigenschaften, nicht um Elemente in Arrays. Siehe Wie überprüfe ich, ob ein Array ein Objekt in JavaScript enthält? für was sonst zu verwenden.
  2. Sie vermissen geschweifte Klammern um die beiden (!) Anweisungen in Ihrem if-Block
  3. Ich bin nicht sicher, ob diese von .remove()Ihnen verwendete Funktion einen Index eines Elements enthält.
Bergi
quelle
2
var data= ["email","role","type","name"];

data.splice(data.indexOf("role"), 1);
data.unshift('role');
Dan Smolinske
quelle
Funktioniert nicht richtig, wenn das ursprüngliche Array nicht enthält "role".
Frambot
2

Ähnlich wie bei @ Tandroid, aber eine allgemeinere Lösung:

const putItemsFirst = ({ findFunction, array }) => [
    ...array.filter(findFunction), 
    ...array.filter(signer => !findFunction(signer)),
]; 

Kann so verwendet werden

putItemsFirst({ 
    array: ["email","role","type","name"], 
    findFunction: item => item === 'role',
})

Ähnliches habe ich letztendlich benutzt,

Petter Sælen
quelle
1

Sie können das Delta des Schecks mit dem gewünschten Wert oben nehmen.

var data = ["email", "role", "type", "name"];

data.sort((a, b) => (b === 'role') - (a === 'role'));

console.log(data);

Nina Scholz
quelle
Dies könnte zu unerwarteten Ergebnissen führen, da ECMAScript vor 2019 nicht Array#sortstabil sein musste. Laut MDN verfügen Internet Explorer und Edge nicht über einen stabilen Sortieralgorithmus.
Str
Edge unterstützt ab Version 79 eine stabile Sortierung!
Isaac Grynsztein
0

Verwenden von lodash _.sortBy . Wenn dies der roleFall ist , wird es zuerst sortiert, andernfalls als zweites. Dies funktioniert auch gut, wenn es keine gibtrole

var data = ["email", "role", "type", "name"];

var sorted = _.sortBy(data, function(item) {
  return item === 'role' ? 0 : 1;
});

console.log(sorted);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Jee Mok
quelle
0

Ich wollte das hier nur fallen lassen, da Guffas Antwort laut anderen Kommentaren an Zugkraft zu gewinnen scheint, das letzte Tertiär - was einer der negativen Kommentare zu dieser Antwort war, ist unnötig. Auch die Verwendung von Pfeilfunktionen lässt es viel sauberer erscheinen.

Es ist auch leicht erweiterbar, um Arrays von Objekten zu handhaben.

const first = "role";
data.sort((x, y) => first === x ? -1 : first === y)

Ich glaube, dies sollte auch die Sorge bewältigen, dass der Rest des Arrays betroffen ist. Wenn die Sortierfunktion eine Zahl kleiner als 0 zurückgibt (first === x), bewegt sich das Element zum Anfang des Arrays, wenn es 0 zurückgibt (first! == y), gibt es keine Bewegung, und wenn a Zahl größer als 0 (erstes === y), x bewegt sich zum Ende des Arrays, alles in Bezug auf x und y. Wenn daher weder x noch y dem gewünschten ersten Element entsprechen (oder dessen Kennung beim Sortieren von Objekten), gibt es keine Bewegung der beiden in Bezug zueinander.

Für ein Objekt:

const unsorted = [{'id': 'test'}, {'id': 'something'}, {'id': 'else'}];
const first = 'something';
const sorted = unsorted.sort((x,y) => x['id'] === first ? -1 : y['id'] === first);
Alex Cartier
quelle
-1
var i = -1;
while (i < data.length) {
    if (data[i] === "role") {
        data.splice(i, 1);
        break;
    }
    i++;
}
data.unshift("role");

indexOfhat nur eingeschränkte Browserunterstützung und wird vom IE7-8 nicht erkannt. Ich würde es also nicht verwenden, wenn ich Sie wäre, selbst auf Kosten der Codepräzision einiger Zeilen. Sie möchten auch ein Semikolon am Ende der Anweisung "Nicht verschieben" einfügen. Das erste Argument von splice () gibt den Index an, mit dem das Entfernen von Elementen gestartet werden soll, und das zweite Argument gibt die Anzahl der zu entfernenden Argumente an.

La-comadreja
quelle
2
Natürlich solltest du es benutzen. Shim es einfach für diese (toten) Browser.
Bergi
-4
var data= ["email","role","type","name"];
if ("role" in data) data.splice(data.indexOf("role"),1); data.unshift("role");
data;
Meister Yoda
quelle
Dies hat die gleichen Probleme wie in der Frage und führt zum gleichen falschen Ergebnis. Der Operator "in" gilt nicht für Arrays, und es fehlen geschweifte Klammern um mehrere Anweisungen, die durch die "if" -Anweisung bedingt werden sollen.
Dan Korn