JavaScript将数组项移到前面

use*_*156 52 javascript arrays

我想检查一个数组是否包含"role".如果是这样,我想移动"role"到数组的前面.

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

在这里,我得到了结果:

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

我怎样才能解决这个问题?

Guf*_*ffa 50

您可以对数组进行排序,并指定值"role"在所有其他值之前,并且所有其他值都相等:

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

演示:http://jsfiddle.net/Guffa/7ST24/

  • 这可能会改变其他项目的顺序,`sort`不稳定. (12认同)
  • ECMAScript 2019 现在要求 [`Array#sort` 保持稳定](https://www.ecma-international.org/ecma-262/10.0/#sec-array.prototype.sort)。 (3认同)
  • 可行,但是嵌套第三层会使代码难以理解 (2认同)

Dav*_*mas 45

我的第一个想法是:

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);
Run Code Online (Sandbox Code Playgroud)

修改,整理一下:

if (data.indexOf('role') > 0) {
    data.splice(data.indexOf('role'), 1);
    data.unshift('role');
}
Run Code Online (Sandbox Code Playgroud)

参考文献:

  • 我认为我们可以通过两次不必使用`Array.indexOf()`函数来做得更好,因为这意味着它要搜索整个数组两次.```const roleIndex = data.indexOf('role'); if(roleIndex> 0){data.splice(roleIndex,1); data.unshift( '角色'); ```` (7认同)
  • `data.splice` 返回刚刚删除的部分,您可以立即使用它来插入,使其成为 1 行而不是 2 行,并且对于更复杂的情况(例如对象数组)也很有用:`data.unshift(data.splice (角色索引, 1)[0])` (3认同)

小智 41

在我看来,ES6中最干净的解决方案:

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

  • 这会忘记在将角色添加回来之前检查角色是否已从列表中删除。 (15认同)
  • 这不是对现有数组进行排序。这假设“角色”存在,保留其他元素,然后在开头强制添加一个硬编码的“角色”。 (2认同)

Rea*_*eal 18

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]
Run Code Online (Sandbox Code Playgroud)

  • 这是迄今为止最好的答案,因为它依赖于索引而不是值。因此,它对于那些希望依赖索引的人和那些希望依赖值的人(可以简单地将“index”替换为“data.findIndex(value)”)都很有用。 (4认同)

小智 12

如果您不想更改现有数组,可以使用ES6解构和filter方法创建新副本,同时保持其他项的顺序.

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


小智 8

如果需要,这是一个不变的解决方案:

      const newData = [
          data.find(item => item === 'role'),
          ...data.filter(item => item !== 'role'),
        ],
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这在函数式编程的纯度方面更好。如果有多个带有“角色”的元素,则添加另一件事,解决方案将仅返回顶部的第一个元素,因为 find 函数仅返回一个元素。一般的解决方案可能是: `const SortedCards = [...data.filter((item) => item === 'NORI'),...cards.filter((item) => item !== 'NORI ')];` (2认同)

Pet*_*len 7

类似于@Tandroid的答案,但更通用的解决方案:

const putItemsFirst = ({ findFunction, array }) => [
    ...array.filter(findFunction), 
    ...array.filter(item => !findFunction(item)),
]; 
Run Code Online (Sandbox Code Playgroud)

可以这样使用

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

我最终使用的是与此类似的东西,


JPR*_*JPR 7

要检查数组中是否存在一个项目,您应该使用.includes()而不是in(正如这里已经指出的,in用于对象中的属性)。

此功能执行您正在寻找的内容:(从项目所在的位置移除项目并在前面阅读)

   
   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);
Run Code Online (Sandbox Code Playgroud)


小智 6

如果您有一组对象,您可以使用 splice 和 push 来移动起始索引。Splice 用数组中从所需索引开始的部分替换原始数组,并返回它删除的部分(索引之前的内容)您推送。

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);
Run Code Online (Sandbox Code Playgroud)


Raj*_*shi 5

我会选择这个 ES6 解决方案。它不会改变原始数组(考虑到它不是嵌套的),不会遍历数组(过滤器),并且您不仅限于移动数组项的第 0 个索引。

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' ]
Run Code Online (Sandbox Code Playgroud)