示例#1
0
Variant ArrayUtil::Shuffle(const Array& input) {
  int count = input.size();
  if (count == 0) {
    return input;
  }

  std::vector<ssize_t> indices;
  indices.reserve(count);
  auto pos_limit = input->iter_end();
  for (ssize_t pos = input->iter_begin(); pos != pos_limit;
       pos = input->iter_advance(pos)) {
    indices.push_back(pos);
  }
  php_array_data_shuffle(indices);

  if (input.isVecArray()) {
    VecArrayInit ret(count);
    for (int i = 0; i < count; i++) {
      ssize_t pos = indices[i];
      ret.append(input->atPos(pos));
    }
    return ret.toVariant();
  } else if (input.isDict()) {
    DictInit ret(count);
    for (int i = 0; i < count; i++) {
      ssize_t pos = indices[i];
      ret.append(input->atPos(pos));
    }
    return ret.toVariant();
  } else if (input.isKeyset()) {
    KeysetInit ret(count);
    for (int i = 0; i < count; i++) {
      ssize_t pos = indices[i];
      ret.add(input->atPos(pos));
    }
    return ret.toVariant();
  } else {
    PackedArrayInit ret(count);
    for (int i = 0; i < count; i++) {
      ssize_t pos = indices[i];
      ret.appendWithRef(input->atPos(pos));
    }
    return ret.toVariant();
  }
}
示例#2
0
Variant ArrayUtil::Shuffle(CArrRef input) {
  int count = input.size();
  if (count == 0) {
    return input;
  }

  std::vector<ssize_t> indices;
  indices.reserve(count);
  for (ssize_t pos = input->iter_begin(); pos != ArrayData::invalid_index;
       pos = input->iter_advance(pos)) {
    indices.push_back(pos);
  }
  php_array_data_shuffle(indices);

  Array ret = Array::Create();
  for (int i = 0; i < count; i++) {
    ssize_t pos = indices[i];
    ret.appendWithRef(input->getValueRef(pos));
  }
  return ret;
}
示例#3
0
Variant ArrayUtil::RandomKeys(const Array& input, int num_req /* = 1 */) {
  int count = input.size();
  if (num_req <= 0 || num_req > count) {
    raise_warning("Second argument has to be between 1 and the "
                  "number of elements in the array");
    return init_null();
  }

  if (num_req == 1) {
    // Iterating through the counter is correct but a bit inefficient
    // compared to being able to access the right offset into array data,
    // but necessary for this code to be agnostic to the array's internal
    // representation.  Assuming uniform distribution, we'll expect to
    // iterate through half of the array's data.
    ssize_t index = f_rand(0, count-1);
    ssize_t pos = input->iter_begin();
    while (index--) {
      pos = input->iter_advance(pos);
    }
    return input->getKey(pos);
  }

  std::vector<ssize_t> indices;
  indices.reserve(count);
  auto pos_limit = input->iter_end();
  for (ssize_t pos = input->iter_begin(); pos != pos_limit;
       pos = input->iter_advance(pos)) {
    indices.push_back(pos);
  }
  php_array_data_shuffle(indices);

  PackedArrayInit ret(num_req);
  for (int i = 0; i < num_req; i++) {
    ssize_t pos = indices[i];
    ret.append(input->getKey(pos));
  }
  return ret.toVariant();
}