Задать вопрос
@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, перемещать последний в начало.
  • Вопрос задан
  • 321 просмотр
Подписаться 2 Простой Комментировать
Решения вопроса 1
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 });
}


или, можно обойтись одним обработчиком:

<button onClick={this.nextHandler} data-step={-1}>prev</button>
<button onClick={this.nextHandler} data-step={+1}>next</button>

nextHandler = (e) => {
  const step = +e.target.dataset.step;

  this.setState(({ items }) => ({
    items: [ ...items.slice(step), ...items.slice(0, step) ],
  }));
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@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 Нижний Новгород
от 80 000 до 120 000 ₽
ITK academy Воронеж
от 50 000 до 90 000 ₽