1

How would i cycle move the key values in a js array,

for example:
    {Name:"A", Task:"Task1"},
    {Name:"B", Task:"Task2"},
    {Name:"C", Task:"Task3"},

to
    {Name:"A", Task:"Task3"},
    {Name:"B", Task:"Task1"},
    {Name:"C", Task:"Task2"},

to clarify further it should be a function that every time is run "shifts the task column" by one.

I have tried using methods such as:

ary.push(ary.shift()); 

however i don't know any way that i can specifically apply this to a specific key while not moving the others.

agwooga33
  • 11
  • 2
  • You mention cycle (as in to loop?), but then you seem to imply transformation? Which is it? What have you tried so far? Please may you add more clarification and a [mcve] of your efforts so far? – evolutionxbox Apr 01 '21 at 22:33
  • 1
    I mean, we have [How to loop through an array containing objects and access their properties](https://stackoverflow.com/q/16626735/215552), but to help you we'd need to know by what logic Task1 has moved to B, Task2 to C and Task3 to A... – Heretic Monkey Apr 01 '21 at 22:35
  • `ary.push()` and `ary.shift()` manipulate the array itself. But it sounds like you want to manipulate the objects inside the array instead. This means you should loop over the array and do the transformation on each object. – Code-Apprentice Apr 01 '21 at 22:44
  • Does this answer your question? [How do I loop through or enumerate a JavaScript object?](https://stackoverflow.com/questions/684672/how-do-i-loop-through-or-enumerate-a-javascript-object) – Ahmed Gaafer Apr 01 '21 at 22:45

3 Answers3

1

Map the array, and take the task from the previous item in the cycle using the modulo operation.

Unlike the % operator the result of using modulo with negative numbers would be a positive remainder. It's needed because in the first item (i is 0) i - 1 would be -1.

const modulo = (a, n) => ((a % n ) + n) % n

const fn = arr =>
  arr.map((o, i) => ({
    ...o,
    Task: arr[modulo((i - 1), arr.length)].Task
  }))

const arr = [{"Name":"A","Task":"Task1"},{"Name":"B","Task":"Task2"},{"Name":"C","Task":"Task3"}]

const result = fn(arr)

console.log(result)
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
0

You are very close. You can decompose the array into two individual ones and shift one of them. See below function:

const arr = [
  { Name: "A", Task: "Task1" },
  { Name: "B", Task: "Task2" },
  { Name: "C", Task: "Task3" }
];

function cycle(arr) {
  const names = arr.map(el => el.Name);
  const tasks = arr.map(el => el.Task);
  const el = tasks.pop();
  tasks.unshift(el);
  return names.map((letter, i) => {
    return {
      Name: letter,
      Task: tasks[i]
    };
  });
}
console.log(cycle(arr));

Also, codepen for conveninence.

Miki
  • 1,625
  • 21
  • 29
0

Approach using a Generator and your pop and shift concept

const data=[{Name:"A",Task:"Task1"},{Name:"B",Task:"Task2"},{Name:"C",Task:"Task3"}];

function* taskGen(data){
   // create standalone array of the names that can be shifted
   const tasks = data.map(({Task}) => Task);
   while(true){
      // move first to last position
      tasks.push(tasks.shift());
      // return new mapped array
      yield data.map((o, i) => ({...o, Task: tasks[i] }))
   }
}

const shifter = taskGen(data);

for (let i =0; i< 6; i++){
   const next = shifter.next().value
   console.log(JSON.stringify(next))
}
.as-console-wrapper {max-height: 100%!important;top:0;}
charlietfl
  • 170,828
  • 13
  • 121
  • 150