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?



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/


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");

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:


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]

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')];

12

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

      const newData = [
          data.find(item => item === 'role'),
          ...data.filter(item => item !== 'role'),
        ],

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);


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)


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' ]


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

data.splice(data.indexOf("role"), 1);
data.unshift('role');

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,


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);


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>


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);

-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.


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;

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.