对于哪些用例,Array.prototype.copyWithin()存在?

时间:2017-12-22 21:41:03

标签: javascript arrays methods copy in-place

很明显,该方法如何运作:

f = ['a','b','c','d','e','f','g','h'];

console.log(f.copyWithin(4,2,5));

//  copy elements between 2 (start) & 5 (end) -> to target -> 4  

//  [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' ] <-- original array
//               ^    ^    ^
//               |    |    |                   <-- [2,5[ = c,d,e
//     0 -  1 -  2 -  3  - 4 -  5 -  6 -  7
//                         |    
//                        'c', 'd', 'e',       <-- copy to 4
//  [ 'a', 'b', 'c', 'd',  |    |    |   'h' ] <-- replace existing elements
//  [ 'a', 'b', 'c', 'd', 'c', 'd', 'e', 'h' ] <-- resulting array

但是,为什么我需要这样的机制?对于哪些用例?

1 个答案:

答案 0 :(得分:4)

以下是一些用例,对于使用copyWithIn方法非常有用。

  1. 实施Insertion Sort Algorithm

const insertionSort = (data, compare) => {
  const arr = [...data];
  let unsort_index = 1;

  while (unsort_index < arr.length) {

    while (arr[unsort_index] >= arr[unsort_index - 1]) unsort_index += 1;
    const pick = arr[unsort_index];

    let iter = 0;
    while (iter < unsort_index && arr[iter] < pick) iter += 1;
    arr.copyWithin(iter + 1, iter, unsort_index);
    arr[iter] = pick;

    unsort_index += 1;
  }
  return arr;
}

const input = [2, 3, 5, 1, 9, 8, 6, 6];
const asc = (a, b) => a - b;
const dsc = (a, b) => b - a;

console.log({ input, asc_sorted: insertionSort(input, asc) });
console.log({ input, dsc_sorted: insertionSort(input, dsc) });

  1. 从数组中移除元素。 (结帐question 1question 2

function deleteItemsFromArray(array, delete_list) {
  for (let i = array.length - 1; i > -1; i--) {
    if (delete_list.includes(array[i])) {
      array.copyWithin(i, i + 1).pop();
    }
  }
}

// Alternate way, with minimal copy/move group of elements.
function deleteItemsFromArrayAlternate(array, delete_list) {
  let index = -1;
  let count = 0;
  for (let i = 0; i <= array.length; i++) {
    if (delete_list.includes(array[i]) || !(i in array)) {
      if (index > -1) {
        array.copyWithin(index - count + 1, index + 1, i);
      }
      count += 1;
      index = i;
    }
  }
  array.length = array.length - delete_list.length;
}

const array = [9, 12, 3, 4, 5, 6, 7];
deleteItemsFromArray(array, [9, 6, 7]);

console.log(array);

  1. 实施自定义编码。 (例如,将适当的字符串更改为%20的空格)。

const myEncode = (str) => {
  const arr = [...str];
  const num_of_spaces = arr.reduce(
    (count, c) => (c === " " ? count + 1 : count),
    0
  );
  arr.length += num_of_spaces * 3;
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] === " ") {
      arr.copyWithin(i + 3, i + 1);
      arr[i] = "%";
      arr[i + 1] = "2";
      arr[i + 2] = "0";
    }
  }
  return arr.join("");
};

console.log(myEncode("this is some str"));
console.log(decodeURIComponent(myEncode("this is some str")));

PS: This code can be optimised if traverse from end to start.

  1. 旋转数组。 (例如,向左旋转一些,向右旋转一些)

const arr = [1, 2, 3, 4, 5, 6];
// rotate to [3, 4, 5, 6, 1, 2];

const rotate = (arr, num) => {
  arr.length += num;
  arr.copyWithin(arr.length - num, 0, num);
  arr.copyWithin(0, num);
  arr.length -= num;
};

rotate(arr, 2)
console.log(arr);