Задать вопрос
@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, перемещать последний в начало.
  • Вопрос задан
  • 308 просмотров
Подписаться 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: Обновление сортировки было моим личным требованием, если нужно можно убрать
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы