js截取数组中的几个元素,在给它放到任意位置

这样的方式如何实现,可以写个方法吗

// 原数组
arr = [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q]
// 选中原数组中的任意几个元素的下标,或是连续的几个元素的下标,push到a数组里面
a = [2,4,5,7,10]
// 或者
a = [2,3,4,5,6]
// 然后把a数组对应的下标元素,在放到原数组中的任意一个位置
// 例如:选中连续的几个元素的下标 a=[2,3,4,5,6],把这些下标对应的元素在放到j元素后面
arr = [a,b,h,i,j,  c,d,e,f,g,   k,l,m,n,o,p,q]
阅读 3k
6 个回答
const arr = [..."abcdefghijklmnopqrstuvwxyz"];
const a = [2, 3, 4, 5, 6];

const picked = arr.filter((_, i) => a.includes(i));
const r = arr.filter((_, i) => !a.includes(i));

const index = r.indexOf("j");
r.splice(index, 0, ...picked);

console.log(r);

已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。

我觉得题主这个问题描述有歧义的,我尝试 按无歧义 解读一下,楼主看是否符合预期。

  1. 题主的核心目的是在一个数组中移动若干元素的位置,进行重新排位,生成新的数组,在这个过程中不会增减或者改变数组元素。
  2. 具体的处理要求是:
    2.1. 从原始数组中不重复的取若干元素的索引位置到 形成一个索引位置序列数组a
    2.2. 然后在原始数组中找到某个特定元素(位置),把数组a对应元素调整插入到其后,形成新的数组序列

从实现上来是说,上面的2.1其实是从元素数组中 提取指定索引元素形成新的数组元素数组A(注意其元素索引关系是对照原始数组的),同时原始数组剩余部分形成了新的数组B。然后在B中找一个特定元素的位置(如果这个特定元素现在对应是A中元素啦,也可以找到对应原来的空位——根据前后剩余元素——这种情况也可以根据情况排除),再把A数组元素插入。

前面 边城 的方法是排除了定位元素存在于A中的情况的,这要看你到底需要什么样的处理。

已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。

这种数组元素处理有啥好纠结的, 直接 for 循环处理就可以了, 非要追加简洁 es6 写法可以在熟悉 es6 的语法后自己去想应该怎么写, 真没必要纠结

已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。

/**
 * 将数组中多个指定下标的元素移动到一起(原地算法)
 * 
 * @param arr 目标数组
 * @param fromIndices 下标数组,包含要移动的元素的原下标,并决定新顺序
 * @param toIndex 指定的要移动的元素中第一个元素的新下标
 * 
 * 时间复杂度 O(n), 其中 n 为 arr 长度
 * 空间复杂度 O(m), 其中 m 为 fromIndices 长度
 */
function moveElements(arr, fromIndices, toIndex) {
  fromIndices = new Set(fromIndices);
  const moved = Array.from(fromIndices, i => arr[i]);
  const movedEnd = toIndex + fromIndices.size;
  for (let i = 0, j = i; j < toIndex; ++i)
    if (!fromIndices.has(i)) arr[j++] = arr[i];
  for (let i = arr.length - 1, j = i; j >= movedEnd; --i)
    if (!fromIndices.has(i)) arr[j--] = arr[i];
  for (let i = toIndex; i < movedEnd; ++i)
    arr[i] = moved[i - toIndex];
}

const arr = [..."abcdefghijklmnopqrstuvwxyz"];
console.log(arr);
moveElements(arr, [2, 3, 4, 5, 6], 5);
console.log(arr);

如果是明确是连续的下标,那其实直接截取区间值即可:

var pickArr = arr.splice(a[0], a.length)
arr.splice(arr.indexOf('j')+1, 0, ...pickArr)

如果是不能明确是不是连续的:

var pickArr = a.map((pi,i) => arr.splice(pi-i, 1)[0])
arr.splice(arr.indexOf('j')+1,0,...pickArr)
已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题