Задать вопрос
@gsdev99

Как реализовать вращение массива?

Есть компонент:

import React from "react";

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      items: [
        {id: 1},
        {id: 2},
        {id: 3},
        {id: 4},
        {id: 5},
      ]
    };
  }

  nextHandler = () => {

  };

  prevHandler = () => {

  };

  render() {
    return (
      <React.Fragment>
        <ul className="list">
          {
            this.state.items.map((item) => {
              return (
                <div
                  key={item.id}
                >
                  <div className="list__item">
                    key={item.id}
                  </div>
                </div>
              );
            })
          }
        </ul>

        <div className="controls">
          <button type="button" onClick={this.prevHandler}>prev</button>
          <button type="button" onClick={this.nextHandler}>next</button>
        </div>
      </React.Fragment>
    );
  }
};

export default App;

При нажатии на кнопку next, необходимо перемещать первый элемент массива items в конец:

items = [
  {id: 2},
  {id: 3},
  {id: 4},
  {id: 5}
  {id: 1},
]

И, соответственно, при нажатии на prev, перемещать последний в начало.
  • Вопрос задан
  • 343 просмотра
Подписаться 2 Простой Комментировать
Помогут разобраться в теме Все курсы
  • Нетология
    Frontend-разработка на React
    10 недель
    Далее
  • ProductStar
    Разработка на React
    6 недель
    Далее
  • Яндекс Практикум
    React-разработчик
    3 месяца
    Далее
Решения вопроса 2
0xD34F
@0xD34F Куратор тега React
Копируем массив, выдёргиваем элемент с одного конца, засовываем с другого:

nextHandler = () => {
  const items = [...this.state.items];
  items.push(items.shift());
  this.setState({ items });
}

prevHandler = () => {
  const items = [...this.state.items];
  items.unshift(items.pop());
  this.setState({ items });
}

Или, можно обойтись одним обработчиком - посредством data-атрибута у кнопок указываем, откуда куда сколько перемещать элементов, используем это значение в качестве индекса для получения двух частей массива, меняем эти части местами:

<button onClick={this.rotate} data-step={-1}>prev</button>
<button onClick={this.rotate} data-step={+1}>next</button>
<button onClick={this.rotate} data-step={-2}>double prev</button>
<button onClick={this.rotate} data-step={+3}>triple next</button>

rotate = ({ target: { dataset: { step } } }) => {
  this.setState(({ items }) => {
    step %= items.length;

    return {
      items: [
        ...items.slice(step),
        ...items.slice(0, step),
      ],
    };
  });
}
Ответ написан
@awenn2015
Веб-разработчик самоучка
Если кто-то будет гуглить и не найдет для себя ответа на вопрос, то вот универсальная реализация, перемещение элемента со смещением соседей по индексам whom и where, может быть полезно в ui где с помощью drag&drop перемещаются элементы в списке или карточки, для вывода сортируясь по полю order

interface Todo {
  id: number
  order: number
  title: string
}

interface Test {
  whom: number
  where: number
  expected: number[]
}

const data: Todo[] = [
  { id: 1, order: 1, title: 'delectus aut autem' },
  { id: 2, order: 2, title: 'quis ut nam facilis et officia qui' },
  { id: 3, order: 3, title: 'fugiat veniam minus' },
  { id: 4, order: 4, title: 'et porro tempora' },
  { id: 5, order: 5, title: 'laboriosam mollitia et enim quasi adipisci quia provident illum' },
  { id: 6, order: 6, title: 'qui ullam ratione quibusdam voluptatem quia omnis' },
  { id: 7, order: 7, title: 'illo expedita consequatur quia in' },
  { id: 8, order: 8, title: 'quo adipisci enim quam ut ab' },
  { id: 9, order: 9, title: 'molestiae perspiciatis ipsa' },
  { id: 10, order: 10, title: 'illo est ratione doloremque quia maiores aut' },
]

function swapTodos(todos: Todo[], whom: number, where: number) {
  if (whom === where) return todos

  const result = (() => {
    if (whom < where) {
      const start = todos.slice(0, whom)
      const neighbors = todos.slice(whom + 1, where + 1)
      const tail = todos.slice(where + 1, todos.length)

      return [...start, ...neighbors, todos[whom], ...tail]
    } else {
      const start = todos.slice(0, where)
      const neighbors = todos.slice(where, whom)
      const tail = todos.slice(whom + 1, todos.length)

      return [...start, todos[whom], ...neighbors, ...tail]
    }
  })()

  return result.map((it, i) => ({ ...it, order: i + 1 }))
}

const tests: Test[] = [
  { whom: 1, where: 5, expected: [1, 3, 4, 5, 6, 2, 7, 8, 9, 10] },
  { whom: 0, where: 9, expected: [2, 3, 4, 5, 6, 7, 8, 9, 10, 1] },
  { whom: 4, where: 9, expected: [1, 2, 3, 4, 6, 7, 8, 9, 10, 5] },
  { whom: 8, where: 3, expected: [1, 2, 3, 9, 4, 5, 6, 7, 8, 10] },
  { whom: 9, where: 0, expected: [10, 1, 2, 3, 4, 5, 6, 7, 8, 9] },
  { whom: 9, where: 4, expected: [1, 2, 3, 4, 10, 5, 6, 7, 8, 9] },
]

function runTests() {
  console.log('-----------------')

  for (const [i, { expected: expect, whom, where }] of tests.entries()) {
    console.log(`[Test ${i + 1} start]`)

    const result = swapTodos(data, whom, where)
    const compare = result.map((it) => it.id)

    if (JSON.stringify(compare) !== JSON.stringify(expect)) {
      console.warn(`[Test ${i + 1} failed]: Результат не соответствует тому что ожидалось`)
      console.log('Result => ', JSON.stringify(compare))
      console.log('Expected => ', JSON.stringify(expect))
    } else {
      console.log(`[Test ${i + 1} passed]: Тест успешно пройден`)
    }

    console.log('-----------------')
  }
}

export default runTests


Ps: Обновление сортировки было моим личным требованием, если нужно можно убрать
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
ITK academy Нижний Новгород
от 50 000 до 90 000 ₽
ITK academy Екатеринбург
от 50 000 до 90 000 ₽
от 250 000 до 300 000 ₽