将元素移动到数组的第一个位置

24

我有一个像这样的对象:

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 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" }, 
]

我尝试过这个:

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

你想按照ID字段排序吗? - Mihai Alexandru-Ionut
是的,我想按ID排序,只按ID排序。 - Mr world wide
1
称其为“排序”是一种不恰当的描述方式。你只想将具有匹配id的条目移动到第一个位置,而不是要求按任何标准对数组中的其他条目进行排序。 - Makyen
3个回答

47

由于您只需将一个项目移动到顶部,因此我将使用 splice()unshift() 将该项目移到顶部:

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


1
可能会起作用,但我不喜欢这种方法,因为它在循环遍历数组时操纵位置。 - Jaider

8
你可以使用 unshift 方法。

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


@Mrworldwide,不,item1和item2是传递给排序函数回调函数的元素。 - Mihai Alexandru-Ionut
@Mrworldwide,您是否想对数组进行排序,但保持“newSortingOrder”作为第一项? - Mihai Alexandru-Ionut
@Mrworldwide,我更新了我的答案。请编辑您的问题。这不是一个排序。 - Mihai Alexandru-Ionut
谢谢您的帮助,我非常感激。实际上它是ES5,所以我正在使用@mamun的答案。 - Mr world wide
2
@Mrworldwide,您可以尝试一种更简单的解决方案:data.sort((a, b)=>{ if(b.id == stringToFilter) return 1;}); - Mihai Alexandru-Ionut
完美的答案,非常感谢! - El7or

7

这里提供一种不同的非变异方法。我只是使用了TypeScript来定义Person,除此之外就是ES6。

基本上我们只需要:

  1. 从原始数组中过滤出该人员
  2. 将其重新插入到开头
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];
}

如果您不介意混合一些内容,可以避免使用spread运算符,改用unshift。我特别不喜欢将改变数组的函数与不改变数组的函数混合使用,但在某些情况下,您可能会获得一些性能改进。例如,对于一个非常长的数组,在保持可读性的同时,对原始方法进行以下更改将略微加速:

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

这两种方法都不会改变arrayOfPersons数组,而是返回一份带有更改的副本。

在这里你可以学习更多关于数组变异方法的知识。https://doesitmutate.xyz/

PS. Person类型可能是这样的:

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

平安!


感谢:) 简洁明了 - YTG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接