最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - For which use cases does Array.prototype.copyWithin() exist? - Stack Overflow

programmeradmin1浏览0评论

It is clear, how does the method work:

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

But, why do I need such mechanism? For which use-cases?

It is clear, how does the method work:

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

But, why do I need such mechanism? For which use-cases?

Share Improve this question asked Dec 22, 2017 at 21:41 user3025289user3025289 12
  • 1 One would be for a buffer, where you read data into a fixed size array, and provide chunks as lines or tokens or something. If you're close to the end of the buffer, and don't have enough data remaining for a plete chunk, you can copy that trailing data to the start of the array, and then write more data from the source starting at the end of that previous data. – user8897421 Commented Dec 22, 2017 at 21:51
  • 1 Why do you say that? – user8897421 Commented Dec 22, 2017 at 21:56
  • 1 like @rockstar said in buffer its a case, you can use buffers in stream scripts, download/upload file data for example if you want a use case for buffers. – Ciro Spaciari Commented Dec 22, 2017 at 21:58
  • 1 @Lonely: You're right that in JS, Arrays are a dynamically sized type, but it still suffers the overhead of allocation. This avoids that. So by "fixed size", I mean you're using it as though it was fixed for efficiency. – user8897421 Commented Dec 22, 2017 at 22:00
  • 3 @Lonely: Why would buffers be exempted as a use case and possible motivation? And if you wanted to know what specific individuals were thinking at some point in the past, this isn't the best place to inquire. – user8897421 Commented Dec 22, 2017 at 22:05
 |  Show 7 more ments

1 Answer 1

Reset to default 11

Here are some of use cases and very useful to use copyWithIn method.

  1. Implementing the Insertion Sort Algorithm.

const insertionSort = (data, pare) => {
  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. Removing elements from array in place. (Checkout question 1, question 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. Implementing custom encode. (Eg. Change spaces to %20 for given string in place).

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. Rotating arrays. (Eg. left rotate by some number, right rotate by some number)

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

发布评论

评论列表(0)

  1. 暂无评论