LoginSignup
0
0

More than 1 year has passed since last update.

【javascript】配列内で指定した範囲を、指定したINDEXに割り込ませる

Last updated at Posted at 2021-05-09

copyWithin()の移動版?

引数

名前 説明
1 arr 扱う配列
2 p 移動先のINDEX
3 f 移動させる範囲の開始位置 INDEX
4 t 移動させる範囲の終了位置 INDEX

開始位置と終了位置は逆になっても問題ない

コード

const moving = (arr, p, f, t) => {
    if (!Array.isArray(arr)
     || p===undefined) return arr;

    const m = arr.length;

    f = f===undefined || f<-m ? 0 : f<0 ? m+f : m<f ? m : f;
    t = t===undefined || m<t ? m : t<-m ? 0 : t<0 ? m+t : t;

    if (f===t
     || (f===0 && t===m)) return arr;

    if (f>t) [f,t] = [t,f];
    p = p<-m ? 0 : p<0 ? m+p : m<p ? m : p;

    if (f<=p && p<=t) return arr;

    if (p<f) {
        return arr.slice(0, p).concat(arr.slice(f, t+1), arr.slice(p, f), arr.slice(t+1, m))
    } else if (t<p) {
        return arr.slice(0, f).concat(arr.slice(t+1, p), arr.slice(f, t+1), arr.slice(p, m))
    }
};

const arr = [...Array(10).keys()];
console.log( moving(arr, -5, -1, -3) ); // [0, 1, 2, 3, 4, 7, 8, 9, 5, 6]
console.log( moving(arr, arr.length, 2, 5) );   // [0, 1, 6, 7, 8, 9, 2, 3, 4, 5]

追記

const moving = (array, p, f, t) => {
    if (!Array.isArray(array) || p===undefined) return array;
    const arr = array.slice();
    const m = arr.length;

    p = p<0 ? (p<-m ? m : p+m) : (m<p ? m : p);
    f = f===undefined ? 0 : f<0 ? (f<-m ? m-1 : f+m) : (m<f ? m-1 : f);
    t = t===undefined ? m-1 : t<0 ? (t<-m ? m-1 : t+m) : (m<t ? m-1 : t);

    if (f>t) [f,t] = [t,f];
    t++;
    if ((f===0&&t===m) || (f<=p&&p<=t)) return arr;

    const range = p<f ? [[0,p],[f,t],[p,f],[t,m]] : [[0,f],[t,p],[f,t],[p,m]];
    const res = [];
    for (let [s,e] of range) while (s<e) res.push(arr[s++]);

    return res;
}
0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0