JavaScript move an item of an array to the front

JavascriptArrays

Javascript Problem Overview


I want to check if an array contains "role". If it does, I want to move the "role" to the front of the array.

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

Here, I got the result:

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

How can I fix this?

Javascript Solutions


Solution 1 - Javascript

You can sort the array and specify that the value "role" comes before all other values, and that all other values are equal:

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

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

Solution 2 - Javascript

The cleanest solution in ES6 in my opinion:

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

Solution 3 - Javascript

My first thought would be:

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

To revise, and tidy up a little:

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

References:

Solution 4 - Javascript

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]

Solution 5 - Javascript

Here is an immutable solution if needed :

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

Solution 6 - Javascript

If you don't want to alter the existing array, you can use ES6 destructuring with the filter method to create a new copy while maintaining the order of the other items.

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

Solution 7 - Javascript

To check whether an item exists in an array you should to use .includes() instead of in (as already noted here, in is for properties in objects).

This function does what you are looking for: (removes the item from the position it is in and reads in front)

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

Solution 8 - Javascript

If you have an array of objects you could shift the start-index with splice and push. Splice replaces the original array with the part of the array starting from the desired index and returns the part it removes (the stuff before the index) which you push.

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

Solution 9 - Javascript

I would go with this ES6 solution. It doesn't mutate the original array(considering it's not nested), doesn't traverse through the array(filter) and you're not just limited to 0th index for shifting the array item.

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

Solution 10 - Javascript

Similar to @Tandroid's answer but a more general solution:

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

Can be used like this

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

Something similar to this is what I ended up using,

Solution 11 - Javascript

You could take the delta of the check with the wanted value at top.

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

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

console.log(data);

Solution 12 - Javascript

A reusable ES6/Typescript solution:

const moveToStart = <T>(array: T[], predicate: (item: T) => boolean): T[] => {
  return array.sort((a, b) => {
    if (predicate(a)) return -1;
    if (predicate(b)) return 1;

    return 0;
  });
};
const data = ["email", "role", "type", "name"];
const result = moveToStart(data, (item) => item === "role"))

Solution 13 - Javascript

  1. the in operator is about properties, not about items in arrays. See https://stackoverflow.com/q/237104/1048572 for what to use else.
  2. You're missing braces around the two (!) statements in your if-block
  3. I'm not sure whether that .remove() function you're using does take an index of an item.

Solution 14 - Javascript

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

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

Solution 15 - Javascript

Using lodash _.sortBy. If the item is role, it will be sorted first, otherwise second. This works fine too if there is no role

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>

Solution 16 - Javascript

Just wanted to drop this on here since according to other comments Guffa's answer seems to be gaining traction, the final tertiary - which was one of the negative comments on that answer is unnecessary. Also using arrow functions makes it seem much cleaner.

Also, it is easily expandable to handling Arrays of objects.

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

I believe this should also handle the worry of the rest of the array being affected. When the sort function returns a number less than 0 (first === x), the element will move toward the start of the Array, when it returns 0 (first !== y), there will be no movement, and when a number greater than 0 (first === y), x will move toward the end of the Array, all in relation to x and y. Therefore, when neither x or y are equivalent to the desired first element (or it's identifier in the case of sorting objects), there will be no movement of the two in relation to each other.

For an object:

const unsorted = [{'id': 'test'}, {'id': 'something'}, {'id': 'else'}];
const first = 'something';
const sorted = unsorted.sort((x,y) => x['id'] === first ? -1 : y['id'] === first);

Solution 17 - Javascript

Generalized one-liners:

const data = ["a", "b", "c", "d", "e", "f"];
const [from, take] = [3, 2];

data.unshift(...data.splice(from, take));
// alternatively
data = [...data.splice(from, take), ...data];
// ["d", "e", "a", "b", "c", "f"]

Solution 18 - Javascript

const moveToFront = (arr, queryStr) =>
  arr.reduce((acc, curr) => {
    if (queryStr === curr) {
      return [curr, ...acc];
    }
    return [...acc, curr];
  }, []);

const data = ['email', 'role', 'type', 'name'];

console.log(moveToFront(data, 'role'))

Solution 19 - Javascript

const moveTargetToBeginningOfArray = (arr, target) => {
    // loop through array
    for (let i = 0; i < arr.length; i++){
        // if current indexed element is the target
        if(arr[i] === target){
            // remove that target element
            arr.splice(i, 1)
            // then add a target element to the beginning of the array
            arr.unshift(target)
        }
    }
    return arr;
};

// quick sanity check, before and after both are correct
const arrayOfStrings = ["email", "role", "type", "name", "role", "role"];
console.log('before:', arrayOfStrings)
console.log('after:', moveTargetToBeginningOfArray(arrayOfStrings, "role"))

// this would also work for numbers
var arrayOfNumbers = [2,4,0,3,0,1,0]
console.log('before:', arrayOfNumbers)
console.log('after:', moveTargetToBeginningOfArray(arrayOfNumbers, 0))

Solution 20 - Javascript

function unshiftFrom(arr, index) {
  if (index > -1 && index < arr.length) {    // validate index
    var [itemToMove] = arr.splice(index, 1)
    arr.unshift(itemToMove)
  }
  return arr   // optional
}

Solution 21 - Javascript

var i = -1;
while (i < data.length) {
    if (data[i] === "role") {
        data.splice(i, 1);
        break;
    }
    i++;
}
data.unshift("role");

indexOf only has limited browser support, not being recognized by IE7-8. So I wouldn't use it if I were you, even at the expense of a few lines' worth of code conciseness. You also want to put a semicolon at the end of the "unshift" statement. splice()'s first argument specifies the index to start removing elements, and the second argument specifies the number of arguments to remove.

Solution 22 - Javascript

data.unshift(data.splice(data.indexOf('role'), 1)[0])

data.indexOf('role') will find the index of 'role' in the array and then the original array is spliced to remove the 'role' element, which is added to the beginning of the array using unshift

Solution 23 - Javascript

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser2634156View Question on Stackoverflow
Solution 1 - JavascriptGuffaView Answer on Stackoverflow
Solution 2 - JavascriptSkylar BrownView Answer on Stackoverflow
Solution 3 - JavascriptDavid ThomasView Answer on Stackoverflow
Solution 4 - JavascriptsdfsdfView Answer on Stackoverflow
Solution 5 - JavascriptMaldororView Answer on Stackoverflow
Solution 6 - JavascriptTandroidView Answer on Stackoverflow
Solution 7 - JavascriptJPRView Answer on Stackoverflow
Solution 8 - JavascriptTamo MaesView Answer on Stackoverflow
Solution 9 - JavascriptRajender JoshiView Answer on Stackoverflow
Solution 10 - JavascriptPetter SælenView Answer on Stackoverflow
Solution 11 - JavascriptNina ScholzView Answer on Stackoverflow
Solution 12 - JavascriptMax KurapovView Answer on Stackoverflow
Solution 13 - JavascriptBergiView Answer on Stackoverflow
Solution 14 - JavascriptDan SmolinskeView Answer on Stackoverflow
Solution 15 - JavascriptJee MokView Answer on Stackoverflow
Solution 16 - JavascriptAlex CartierView Answer on Stackoverflow
Solution 17 - JavascriptLukasz MatysiakView Answer on Stackoverflow
Solution 18 - JavascriptgiddygitauView Answer on Stackoverflow
Solution 19 - JavascriptjasonleonhardView Answer on Stackoverflow
Solution 20 - JavascriptJoshuaView Answer on Stackoverflow
Solution 21 - JavascriptLa-comadrejaView Answer on Stackoverflow
Solution 22 - JavascriptJoakim WahlströmView Answer on Stackoverflow
Solution 23 - JavascriptMaster YodaView Answer on Stackoverflow