Mr world wide
Mr world wide

Reputation: 4844

Move element to first position in array

I have an object like this:

var data = [
    { id: "fmgbwe45", age: 24, gender: "male"   },
    { id: "kjregh23", age: 27, gender: "female" }, 
    { id: "kjfdhg87", age: 30, gender: "male" }, 
    { id: "lsdjfk43", age: 10, gender: "female" }, 
]

I want to sort the object, this is my expected output:

var data = [
    { id: "kjfdhg87", age: 30, gender: "male" },  //only one record will match in my sort
    { id: "fmgbwe45", age: 24, gender: "male"   },
    { id: "kjregh23", age: 27, gender: "female" }, 
    { id: "lsdjfk43", age: 10, gender: "female" }, 
]

I have tried this:

$scope.sort_by = function (newSortingOrder) {
    var stringToFilter = newSortingOrder.toString();   //this holds 'kjfdhg87'
    var obj = data.sort(function(o) { return o.id - stringToFilter; });
    var finalObj = [obj];
    sortedData = finalObj;
    console.log(sortedData ); //sorting is not working as expected where im doing wrong.
}

Upvotes: 26

Views: 52855

Answers (3)

WSD
WSD

Reputation: 3597

Here's a different non-mutating approach. I'm using TypeScript just for the Person definition, but other than that is just ES6.

Basically we just need to:

  1. Filter out the person from the original array
  2. Insert it again at the beginning
movePersonInArray(person: Person, arrayOfPersons: Person[]): Person[] {
    // remove the item from the array
    const filteredArrayOfPersons = arrayOfPersons.filter((p: Person) => p.id !== person.id);
    // add it at the beginning
    return [{ ...person }, ...filteredArrayOfPersons];
}

If you don't mind mixing things a bit, you can avoid the spread operator and use unshift instead. I particularly don't like to mix functions that mutate the array with those that don't, but in certain scenarios, you may get some performance improvements. For example, for a very long array, the following change in the original method will speed up things a bit while keeping the legibility.

movePersonInArray(person: Person, arrayOfPersons: Person[]): Person[] {
    // remove the item from the array
    const filteredArrayOfPersons = arrayOfPersons.filter((p: Person) => p.id !== person.id);
    // add it at the beginning
    filteredArrayOfPersons.unshift({...person});
    return filteredArrayOfPersons;
}

Neither of these two approaches mutates the arrayOfPersons array, instead, they return a copy with the changes. Here you can learn more about array mutation methods https://doesitmutate.xyz/

PS. The Person type can be something like this:

export interface Person {
id: string;
name: string;
age: number;
}

Peace!

Upvotes: 8

Mamun
Mamun

Reputation: 68933

Since you are just moving one item to the top, I will just use splice() and unshift() the item:

var data = [
    { id: "fmgbwe45", age: 24, gender: "male"   },
    { id: "kjregh23", age: 27, gender: "female" }, 
    { id: "kjfdhg87", age: 30, gender: "male" }, 
    { id: "lsdjfk43", age: 10, gender: "female" }, 
]
data.forEach(function(item,i){
  if(item.id === "kjfdhg87"){
    data.splice(i, 1);
    data.unshift(item);
  }
});

console.log(data);

Upvotes: 50

Mihai Alexandru-Ionut
Mihai Alexandru-Ionut

Reputation: 48437

You can use unshift method.

var data = [
    { id: "fmgbwe45", age: 24, gender: "male"   },
    { id: "kjregh23", age: 27, gender: "female" }, 
    { id: "kjfdhg87", age: 30, gender: "male" }, 
    { id: "lsdjfk43", age: 10, gender: "female" }, 
]

var stringToFilter = 'kjfdhg87';   //this holds 'kjfdhg87'
data.unshift(data.splice(data.findIndex(item => item.id === stringToFilter), 1)[0])
console.log(data);

Upvotes: 10

Related Questions