删除元素时如何保留数组键?

时间:2015-12-14 08:08:48

标签: javascript arrays

我想通过随机插入字符来构建文本字符串,但是按顺序插入(作为一种效果)。到目前为止我已经:

// make a string and an array
var input = "Hello, world!",
    output = [];
// split the string
input = input.split('');

我的想法是打电话给这个

function addAnElement(){
  // check if there are any left
  if(input.length){
     // pick an element at random
     var rand = Math.floor(Math.random() * input.length);
     // remove it, so we don't call it again
     var element = input.splice(rand,1);
     // insert it
     output[rand] = element;
     // use the string returned as new innerHTML, for example 
     return output.join('');
     // repeat until finished
     setTimeout(addAnElement,5);
  }
}

我希望这会返回类似的内容:

'e'
'er'
...
'Hel, or!'
...
'Helo, Word!'
... and finally ...
'Hello, World!'

问题当然是在拼接时重新索引数组 - 这会产生乱码。我认为答案必须是将元素链接到input中的位置,然后将它们完整地插入,必要时在返回之前按键排序。 我该怎么做?

2 个答案:

答案 0 :(得分:1)

这样的事情怎么样:

#include <iostream>
#include <chrono>
#include <string>

template <typename T, size_t N, typename Derived>
struct Base
{
    __forceinline Derived& operator+=(const Derived &b)
    {
        return (static_cast<Derived&>(*this) = static_cast<Derived&>(*this) + b);
    }
};

// same as Base, but with manually inlined operator+
template <typename T, size_t N, typename Derived>
struct Base2
{
    __forceinline Derived& operator+=(const Derived &b)
    {
        static_cast<Derived*>(this)->data[0] += b.data[0];
        static_cast<Derived*>(this)->data[1] += b.data[1];
        static_cast<Derived*>(this)->data[2] += b.data[2];
        static_cast<Derived*>(this)->data[3] += b.data[3];

        return static_cast<Derived&>(*this);
    }
};

template <typename T, size_t N>
struct A: Base<T,N, A<T,N>>
{
    T data[N];
};

template <typename T, size_t N>
struct B: Base2<T,N, B<T,N>>
{
    T data[N];
};

template <typename T, size_t N>
__forceinline A<T, N> operator+(const A<T, N> &a, const A<T, N> &b)
{
    A<T, N> result;

    result.data[0] = a.data[0] + b.data[0];
    result.data[1] = a.data[1] + b.data[1];
    result.data[2] = a.data[2] + b.data[2];
    result.data[3] = a.data[3] + b.data[3];

    return result;
}

template <class Func>
void runtime_print(Func &&func, size_t n, std::string label)
{
    auto t0 = std::chrono::high_resolution_clock::now();
    for (size_t i = 0; i < n; ++i)
    {
        func(i);
    }
    auto t1 = std::chrono::high_resolution_clock::now();

    auto t = std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0).count();

    std::cout << label << " : " << t << '\n';
}


int main()
{
    size_t n = 10000000;

    A <float,4> a0;
    A <float,4> a1;

    B <float,4> b0;
    B <float,4> b1;

    // this is slow
    runtime_print([&](size_t i)
    {
        a0 += a1;
    }, n, "a0");

    // this is fast
    runtime_print([&](size_t i)
    {
        b0 += b1;
    }, n, "b0");

    return 0;
};

http://jsfiddle.net/fg2ybz8j/

答案 1 :(得分:0)

您可以通过不使用var entriesLeft = input.length; function addAnElement(){ // pick an element at random, re-picking if we've already // picked that one var rand; do { rand = Math.floor(Math.random() * input.length); } while (!input[rand]); // get it var element = input[rand]; // clear it, so we don't use it again input[rand] = undefined; // insert it output[rand] = element; // repeat until finished if (--entriesLeft) { setTimeout(addAnElement,5); } // use the string returned as new innerHTML, for example return output.join(''); } 来避免它。相反,在您使用该条目时清除该条目,并记录您已清除的条目。

E.g:

var input = "Hello, there!".split("");
var output = [];
var entriesLeft = input.length;

function addAnElement() {
  // pick an element at random, re-picking if we've already
  // picked that one
  var rand;
  do {
    rand = Math.floor(Math.random() * input.length);
  }
  while (!input[rand]);

  // get it
  var element = input[rand];
  // clear it, so we don't use it again
  input[rand] = undefined;
  // insert it
  output[rand] = element;
  // repeat until finished
  if (--entriesLeft) {
    setTimeout(addAnElement, 5);
  }
  // use the string returned as new innerHTML, for example 
  document.body.innerHTML = output.join('');
}

addAnElement();

当然,对于最后几个字符,选择随机数的循环可能会持续一段时间。如果你担心这一点,你可以创建一个随机的索引数组来预先使用。 This question and its answers解决了这个问题。

直播示例:

&#13;
&#13;
setTimeout
&#13;
&#13;
&#13;

附注:请注意我在return 之前将调用移至return 的方式。 setTimeout退出该功能,因此不会对return output.join('');进行任何调用。也就是说,我对document.body.innerHTML的需要感到困惑;所有的呼叫,但第一个是通过计时器机制,它不关心返回值。在实际示例中,我已使用shuffle的分配替换了该返回。

这里演示了一种改组索引数组的方法。它使用了这个答案中的function shuffle(array) { var tmp, current, top = array.length; if (top) while (--top) { current = Math.floor(Math.random() * (top + 1)); tmp = array[current]; array[current] = array[top]; array[top] = tmp; } return array; } var input = "Hello, there".split(""); var output = []; var indexes = input.map(function(entry, index) { return index; }); shuffle(indexes); var n = 0; function addAnElement() { // get this index var index = indexes[n]; // get this loop's element var element = input[index]; // insert it output[index] = element; // repeat until finished if (++n < indexes.length) { setTimeout(addAnElement, 5); } // use the string returned as new innerHTML, for example document.body.innerHTML = output.join(""); } addAnElement();方法,但我并不是说它必然是最好的随机播放方法。

&#13;
&#13;
public class User {
private int id;
private String medicine;
private String quantity;
private String date;
private String time;   

public User(String time, String medicine, String quantity, String date) {
    this.time = time;
    this.medicine = medicine;
    this.quantity = quantity;
    this.date = date;
}

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getMedicine() {
    return medicine;
}

public void setMedicine(String medicine) {
    this.medicine = medicine;
}

public String getQuantity() {
    return quantity;
}

public void setQuantity(String quantity) {
    this.quantity = quantity;
}

public String getDate() {
    return date;
}

public void setDate(String date) {
    this.date = date;
}

public String getTime() {
    return time;
}

public void setTime(String time) {
    this.time = time;
}
&#13;
&#13;
&#13;