交换数组中未排序的前两个元素

时间:2019-09-28 05:28:59

标签: arrays ruby

我正在尝试编写代码,以查找乱序的数组中的前两个元素并交换它们。我写了这段代码,但是运行时只打印出3个。有人可以帮我重写代码使其正常工作吗?

<i class="fas fa-sync-alt RefreshButtonDataTable" onclick="ClearDataTableStorageAndRefresh()"></i>
     <script>
          function ClearDataTableStorageAndRefresh() {
              ClearLocalStorageDataTables_tbl();
               $('#tbl_SearchTasks').DataTable().ajax.reload();
           }
     </script>



function ClearLocalStorageDataTables_tbl() {
    debugger;
    var arr = []; // Array to hold the keys
    // Iterate over localStorage and insert the keys that meet the condition into arr
    for (var i = 0; i < localStorage.length; i++) {
        if (localStorage.key(i).substring(0, 14) == 'DataTables_tbl') {
            arr.push(localStorage.key(i));
        }
    }

    // Iterate over arr and remove the items by key
    for (var i = 0; i < arr.length; i++) {
        localStorage.removeItem(arr[i]);
    }

    new Noty({
        type: 'success',
        theme: 'metroui',
        layout: 'bottomRight',
        text: 'Datatable Temporary Storage Cleared',
        progressBar: true,
        timeout: 5000
    }).show();
}

3 个答案:

答案 0 :(得分:5)

您可以编写以下内容:

import React, { useState } from "react";
import PropTypes from "prop-types";
import { Row, Col } from "react-bootstrap";

// CC
import CCProgressBar from "../CCProgressBar";
import CCButton from "../CCButton";
import CCFlowAnswer from "../CCFlowAnswer/";

// Local Assets and CSS
import "./CCFlow.css";

const CCFlow = ({ style, questions, answers, loaderLogic, handleSubmit }) => {
  // State
  const [currentQuestion, setCurrentQuestion] = useState(0);
  const [usersAnswers, setUsersAnswers] = useState(initUsersAnswers());

  // Helpers
  function initUsersAnswers() {
    const usersAnswers = {};
    questions.forEach((question, index) => {
      usersAnswers[`answer${index + 1}`] = null;
    });
    return usersAnswers;
  }

  function onLastQuestion() {
    return currentQuestion === questions.length - 1;
  }

  function progress() {
    const total = 100 / questions.length;
    return Math.round(total * (currentQuestion + 1));
  }

  function currentAnswerKey() {
    return `answer${currentQuestion + 1}`;
  }

  // Actions
  function handleNextButtonClick() {
    currentQuestion === questions.length - 1
      ? handleSubmit(usersAnswers)
      : setCurrentQuestion(currentQuestion + 1);
  }

  function handleBackButtonClick() {
    currentQuestion !== 0
      ? setCurrentQuestion(currentQuestion - 1)
      : window.history.back();
  }

  function saveAnswer(answer, answerKey) {
    setUsersAnswers({ ...usersAnswers, [answerKey]: answer });
  }

  return (
    <div className="ccQuestions" style={style ? style : {}}>
      <Row>
        <Col xs={3}>
          <h4 style={{ minHeight: "80px" }}>{questions[currentQuestion]} </h4>
          <div id="ccFlowRow">
            <CCProgressBar width="200px" now={progress()}></CCProgressBar>
            <span>{`${progress()}%`}</span>
          </div>
          <div id="ccFlowButtons">
            <CCButton variant="dark" onClick={handleBackButtonClick}>
              {currentQuestion === 0 ? "Exit" : "Back"}
            </CCButton>
            <CCButton
              style={{ marginLeft: "15px" }}
              variant={onLastQuestion() ? "primary" : "info"}
              onClick={handleNextButtonClick}
              disabled={usersAnswers[currentAnswerKey()] ? false : true}
            >
              {onLastQuestion() ? "Create" : "Next"}
            </CCButton>
          </div>
        </Col>
        <Col xs={9}>
          <CCFlowAnswer
            FlowAnswer={answers[currentQuestion]}
            loadBefore={loaderLogic[currentQuestion]}
            handleAnswer={answer =>
              saveAnswer(answer, `answer${currentQuestion + 1}`)
            }
            answer={
              usersAnswers[currentAnswerKey()]
                ? usersAnswers[currentAnswerKey()]
                : null
            }
          />
        </Col>
      </Row>
    </div>
  );
};

CCFlow.defaultProps = {
  questions: [],
  answers: [],
  waitForAnswers: []
};

CCFlow.propTypes = {
  style: PropTypes.object,
  questions: PropTypes.arrayOf(PropTypes.string),
  answers: PropTypes.arrayOf(PropTypes.elementType),
  loaderLogic: PropTypes.arrayOf(PropTypes.any),
  handleSubmit: PropTypes.func,
  waitForAnswers: PropTypes.arrayOf(PropTypes.bool)
};

export default CCFlow;


arr = [5, 22, 29, 39, 19, 51, 78, 96, 84]

答案 1 :(得分:3)

您当前代码的问题是:

arr[i] = arr[i + 1]
arr[i + 1] = arr[i]

在将arr[i]设置为等于arr[i + 1]的地方,然后用arr[i + 1](设置为arr[i])来重复arr[i + 1]的内容。这会将两个元素都设置为arr[i + 1]的内容。您可以使用一个临时变量来保存arr[i]的先前值。

tmp = arr[i]
arr[i] = arr[i + 1]
arr[i + 1] = tmp

一种更干净的方法是使用multiple assignment

arr[i], arr[i + 1] = arr[i + 1], arr[i]

这消除了对临时变量的需要。


Cary SwovelandiGian的答案中汲取灵感。这是找到索引并交换值的另一种重构方法。

arr = [5, 22, 29, 39, 19, 51, 78, 96, 84]
i = arr.each_cons(2).find_index { |a, b| a > b }
arr[i, 2] = arr[i, 2].reverse if i

arr #=> [5, 22, 29, 19, 39, 51, 78, 96, 84]

答案 2 :(得分:1)

您可以结合使用Enumerable#each_consEnumerable#each_winth_index来获取对及其索引(*)。 然后Enumerable#find以相反的顺序对的第一个索引,Object#then修改插入交换对的原始数组:

arr = [1,2,3,5,4]

arr.each_cons(2).with_index.find { |(a, b), i| a > b }
   .then { |e, i| arr[i..i+1] = e.reverse if i }

arr
#=> [1, 2, 3, 4, 5]

(*)工作原理:

arr.each_cons(2).with_index.to_a
#=> [[[1, 2], 0], [[2, 3], 1], [[3, 5], 2], [[5, 4], 3]]

注意:对于旧版Ruby使用Object#yield_self代替Object#then