PL / SQL включает базовый для списков, разделенных запятыми (DBMS_UTILITY.COMMA_TO_TABLE
).
Пример:
DECLARE
lv_tab_length BINARY_INTEGER;
lt_array DBMS_UTILITY.lname_array;
BEGIN
DBMS_UTILITY.COMMA_TO_TABLE( list => 'one,two,three,four'
, tablen => lv_tab_length
, tab => lt_array
);
DBMS_OUTPUT.PUT_LINE( 'lv_tab_length = ['||lv_tab_length||']' );
FOR i IN 1..lv_tab_length
LOOP
DBMS_OUTPUT.PUT_LINE( '['||lt_array( i )||']' );
END LOOP;
END;
/
Или см. ссылку Ask Tom для других идей. ..
let filled = [];
filled.length = 10;
filled.fill(0);
console.log(filled);
Я знал, что где-то у меня был этот прототип :)
Array.prototype.init = function(x,n)
{
if(typeof(n)=='undefined') { n = this.length; }
while (n--) { this[n] = x; }
return this;
}
var a = (new Array(5)).init(0);
var b = [].init(0,4);
Edit: tests
В ответ на методы Джошуа и других я провел свой собственный тест, и я увидел совершенно другое
Вот то, что я тестировал:
//my original method
Array.prototype.init = function(x,n)
{
if(typeof(n)=='undefined') { n = this.length; }
while (n--) { this[n] = x; }
return this;
}
//now using push which I had previously thought to be slower than direct assignment
Array.prototype.init2 = function(x,n)
{
if(typeof(n)=='undefined') { n = this.length; }
while (n--) { this.push(x); }
return this;
}
//joshua's method
function newFilledArray(len, val) {
var a = [];
while(len--){
a.push(val);
}
return a;
}
//test m1 and m2 with short arrays many times 10K * 10
var a = new Date();
for(var i=0; i<10000; i++)
{
var t1 = [].init(0,10);
}
var A = new Date();
var b = new Date();
for(var i=0; i<10000; i++)
{
var t2 = [].init2(0,10);
}
var B = new Date();
//test m1 and m2 with long array created once 100K
var c = new Date();
var t3 = [].init(0,100000);
var C = new Date();
var d = new Date();
var t4 = [].init2(0,100000);
var D = new Date();
//test m3 with short array many times 10K * 10
var e = new Date();
for(var i=0; i<10000; i++)
{
var t5 = newFilledArray(10,0);
}
var E = new Date();
//test m3 with long array created once 100K
var f = new Date();
var t6 = newFilledArray(100000, 0)
var F = new Date();
Результаты:
IE7 deltas:
dA=156
dB=359
dC=125
dD=375
dE=468
dF=412
FF3.5 deltas:
dA=6
dB=13
dC=63
dD=8
dE=12
dF=8
Итак, по моим подсчетам, push действительно медленнее в целом, но работает лучше с более длинными массивами в FF, но хуже в IE, что в целом отстой (quel сюрприз ).
function makeArrayOf(value, length) {
var arr = [], i = length;
while (i--) {
arr[i] = value;
}
return arr;
}
makeArrayOf(0, 5); // [0, 0, 0, 0, 0]
makeArrayOf('x', 3); // ['x', 'x', 'x']
Обратите внимание, что , а
обычно более эффективен, чем for-in
, forEach
и т. Д.
Я протестировал все комбинации предварительного выделения / отсутствия предварительного выделения, подсчета вверх / вниз и циклов for / while в IE 6/7/8, Firefox 3.5, Chrome и Opera.
Приведенные ниже функции всегда были самыми быстрыми или очень близкими в Firefox, Chrome и IE8, и ненамного медленнее, чем самые быстрые в Opera и IE 6. На мой взгляд, они также самые простые и понятные. Я нашел несколько браузеров, в которых версия цикла while немного быстрее, поэтому я также включаю ее для справки.
function newFilledArray(length, val) {
var array = [];
for (var i = 0; i < length; i++) {
array[i] = val;
}
return array;
}
или
function newFilledArray(length, val) {
var array = [];
var i = 0;
while (i < length) {
array[i++] = val;
}
return array;
}
Примечание добавлено в августе 2013 г., обновлено в феврале 2015 г .: Приведенный ниже ответ от 2009 г. относится к общему типу JavaScript Array
. Это не относится к более новым типизированным массивам, определенным в ES2015 [и теперь доступным во многих браузерах], таким как Int32Array
и т.п. Также обратите внимание, что ES2015 добавляет метод fill
к типизированным массивам Arrays и , что, вероятно, будет наиболее эффективным способом их заполнения ...
Кроме того, это может иметь большое значение для некоторых реализаций того, как вы создаете массив. Механизм Chrome V8, в частности, пытается использовать высокоэффективный массив непрерывной памяти, если считает, что это возможно, переходя к объектно-ориентированному массиву только при необходимости.
В большинстве языков это будет предварительно выделено, затем заполнение нулями, вот так: По-видимому, добавление элементов в массив в обратном порядке - медленная операция в Firefox. Фактически, результаты довольно сильно различаются в зависимости от реализации JavaScript (что не так уж удивительно). Вот быстрая и грязная тестовая страница (ниже) для реализаций браузера (очень грязная, не срабатывает во время тестов, поэтому обеспечивает минимальную обратную связь и будет нарушать ограничения по времени скрипта). Я рекомендую обновляться между тестами; FF (по крайней мере) замедляется при повторных тестах, если вы этого не сделаете.
Достаточно сложная версия, использующая Array # concat, быстрее, чем прямая инициализация на FF, где-то между 1000 и 2000 массивами элементов. Однако на движке Chrome V8 прямой init побеждает каждый раз ...
Вот тестовая страница ( живая копия ):
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Zero Init Test Page</title>
<style type='text/css'>
body {
font-family: sans-serif;
}
#log p {
margin: 0;
padding: 0;
}
.error {
color: red;
}
.winner {
color: green;
font-weight: bold;
}
</style>
<script type='text/javascript' src='prototype-1.6.0.3.js'></script>
<script type='text/javascript'>
var testdefs = {
'downpre': {
total: 0,
desc: "Count down, pre-decrement",
func: makeWithCountDownPre
},
'downpost': {
total: 0,
desc: "Count down, post-decrement",
func: makeWithCountDownPost
},
'up': {
total: 0,
desc: "Count up (normal)",
func: makeWithCountUp
},
'downandup': {
total: 0,
desc: "Count down (for loop) and up (for filling)",
func: makeWithCountDownArrayUp
},
'concat': {
total: 0,
desc: "Concat",
func: makeWithConcat
}
};
document.observe('dom:loaded', function() {
var markup, defname;
markup = "";
for (defname in testdefs) {
markup +=
"<div><input type='checkbox' id='chk_" + defname + "' checked>" +
"<label for='chk_" + defname + "'>" + testdefs[defname].desc + "</label></div>";
}
$('checkboxes').update(markup);
$('btnTest').observe('click', btnTestClick);
});
function epoch() {
return (new Date()).getTime();
}
function btnTestClick() {
// Clear log
$('log').update('Testing...');
// Show running
$('btnTest').disabled = true;
// Run after a pause while the browser updates display
btnTestClickPart2.defer();
}
function btnTestClickPart2() {
try {
runTests();
}
catch (e) {
log("Exception: " + e);
}
// Re-enable the button; we don't yheidl
$('btnTest').disabled = false;
}
function runTests() {
var start, time, counter, length, defname, def, results, a, invalid, lowest, s;
// Get loops and length
s = $F('txtLoops');
runcount = parseInt(s);
if (isNaN(runcount) || runcount <= 0) {
log("Invalid loops value '" + s + "'");
return;
}
s = $F('txtLength');
length = parseInt(s);
if (isNaN(length) || length <= 0) {
log("Invalid length value '" + s + "'");
return;
}
// Clear log
$('log').update('');
// Do it
for (counter = 0; counter <= runcount; ++counter) {
for (defname in testdefs) {
def = testdefs[defname];
if ($('chk_' + defname).checked) {
start = epoch();
a = def.func(length);
time = epoch() - start;
if (counter == 0) {
// Don't count (warm up), but do check the algorithm works
invalid = validateResult(a, length);
if (invalid) {
log("<span class='error'>FAILURE</span> with def " + defname + ": " + invalid);
return;
}
}
else {
// Count this one
log("#" + counter + ": " + def.desc + ": " + time + "ms");
def.total += time;
}
}
}
}
for (defname in testdefs) {
def = testdefs[defname];
if ($('chk_' + defname).checked) {
def.avg = def.total / runcount;
if (typeof lowest != 'number' || lowest > def.avg) {
lowest = def.avg;
}
}
}
results =
"<p>Results:" +
"<br>Length: " + length +
"<br>Loops: " + runcount +
"</p>";
for (defname in testdefs) {
def = testdefs[defname];
if ($('chk_' + defname).checked) {
results += "<p" + (lowest == def.avg ? " class='winner'" : "") + ">" + def.desc + ", average time: " + def.avg + "ms</p>";
}
}
results += "<hr>";
$('log').insert({top: results});
}
function validateResult(a, length) {
var n;
if (a.length != length) {
return "Length is wrong";
}
for (n = length - 1; n >= 0; --n) {
if (a[n] != 0) {
return "Index " + n + " is not zero";
}
}
return undefined;
}
function makeWithCountDownPre(len) {
var a;
a = new Array(len);
while (--len >= 0) {
a[len] = 0;
}
return a;
}
function makeWithCountDownPost(len) {
var a;
a = new Array(len);
while (len-- > 0) {
a[len] = 0;
}
return a;
}
function makeWithCountUp(len) {
var a, i;
a = new Array(len);
for (i = 0; i < len; ++i) {
a[i] = 0;
}
return a;
}
function makeWithCountDownArrayUp(len) {
var a, i;
a = new Array(len);
i = 0;
while (--len >= 0) {
a[i++] = 0;
}
return a;
}
function makeWithConcat(len) {
var a, rem, currlen;
if (len == 0) {
return [];
}
a = [0];
currlen = 1;
while (currlen < len) {
rem = len - currlen;
if (rem < currlen) {
a = a.concat(a.slice(0, rem));
}
else {
a = a.concat(a);
}
currlen = a.length;
}
return a;
}
function log(msg) {
$('log').appendChild(new Element('p').update(msg));
}
</script>
</head>
<body><div>
<label for='txtLength'>Length:</label><input type='text' id='txtLength' value='10000'>
<br><label for='txtLoops'>Loops:</label><input type='text' id='txtLoops' value='10'>
<div id='checkboxes'></div>
<br><input type='button' id='btnTest' value='Test'>
<hr>
<div id='log'></div>
</div></body>
</html>
с использованием объектной нотации
var x = [];
заполнено нулями? как ...
var x = [0,0,0,0,0,0];
заполнено 'undefined' ...
var x = new Array(7);
нотация obj с нулями
var x = [];
for (var i = 0; i < 10; i++) x[i] = 0;
В качестве примечания: если вы измените прототип Array, оба
var x = new Array();
и
var y = [];
будут иметь эти модификации прототипа
Во всяком случае, меня бы не слишком беспокоила эффективность или скорость этой операции, вы, вероятно, будете делать множество других вещей, которые намного расточительнее и дороже, чем создание экземпляра массива произвольной длины, содержащего нули. .
Моя самая быстрая функция:
function newFilledArray(len, val) {
var a = [];
while(len--){
a.push(val);
}
return a;
}
var st = (new Date()).getTime();
newFilledArray(1000000, 0)
console.log((new Date()).getTime() - st); // returned 63, 65, 62 milliseconds
Использование собственных push и shift для добавления элементов в массив намного быстрее (примерно в 10 раз), чем объявление области массива и ссылка на каждый элемент для установки это значение.
к сведению: я постоянно получаю более быстрое время с первым циклом, который идет обратным отсчетом, при запуске этого в firebug (расширение firefox).
var a = [];
var len = 1000000;
var st = (new Date()).getTime();
while(len){
a.push(0);
len -= 1;
}
console.log((new Date()).getTime() - st); // returned 863, 894, 875 milliseconds
st = (new Date()).getTime();
len = 1000000;
a = [];
for(var i = 0; i < len; i++){
a.push(0);
}
console.log((new Date()).getTime() - st); // returned 1155, 1179, 1163 milliseconds
Мне интересно знать, что TJ Crowder делает из этого? : -)
var str = "0000000...0000";
var arr = str.split("");
использование в выражениях: arr [i] * 1;
РЕДАКТИРОВАТЬ: если arr
предполагается использовать в целочисленных выражениях, пожалуйста, не Обратите внимание на значение символа "0". Вы просто используете его следующим образом: a = a * arr [i]
(при условии, что a
имеет целочисленное значение).