2010-11-11 4 views
588

У меня есть массив javascript dataArray, который я хочу нажать в новый массив newArray. За исключением я не хочу newArray[0] быть dataArray. Я хочу, чтобы нажать на все значения в новый массив:Javascript переносит значения массива в другой массив

var newArray = []; 

newArray.pushValues(dataArray1); 
newArray.pushValues(dataArray2); 
// ... 

или даже лучше:

var newArray = new Array (
    dataArray1.values(), 
    dataArray2.values(), 
    // ... where values() (or something equivalent) would push the individual values into the array, rather than the array itself 
); 

Так что теперь новый массив содержит все значения отдельных массивов данных. Есть ли какая-то стенография, например pushValues, поэтому мне не нужно перебирать каждый отдельный dataArray, добавляя значения 1 на 1?

+0

Посмотреть этот адрес http://stackoverflow.com/questions/ 351409/appending-to-array –

+0

Это должен быть ответ https://davidwalsh.name/combining-js-arrays – starikovs

ответ

778

Используйте функцию concat, например, так:

var arrayA = [1, 2]; 
var arrayB = [3, 4]; 
var newArray = arrayA.concat(arrayB); 

Значение newArray будет [1, 2, 3, 4] (arrayA и arrayB остаются неизменными; concat создает и возвращает новый массив для результата).

+4

Лучшей ссылкой было бы: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/concat [1]: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/concat –

+64

Медленно, хотя: http://jsperf.com/concat-vs-push-apply/10 – w00t

+2

Ответ ниже, более подробно, я согласен, что я мог бы назначить это как правильный ответ. – WiseGuyEh

10
var a=new Array('a','b','c'); 
var b=new Array('d','e','f'); 
var d=new Array('x','y','z'); 
var c=a.concat(b,d) 

Решения для решения этой проблемы?

549

Если ваши массивы не огромны (см. Ниже), вы можете использовать метод массива push(), к которому вы хотите добавить значения. push() может принимать несколько параметров, поэтому вы можете использовать его метод apply() для передачи массива значений, которые будут отображаться в виде списка параметров функции. Это имеет преимущество перед использованием concat() добавления элементов в массив вместо того, чтобы создавать новый массив.

Однако, похоже, что для больших массивов (порядка 100 000 членов или более) этот трюк может не работать. Для таких массивов использование цикла является лучшим подходом. См. https://stackoverflow.com/a/17368101/96100.

var newArray = []; 
newArray.push.apply(newArray, dataArray1); 
newArray.push.apply(newArray, dataArray2); 

Вы можете обобщить это в функцию:

function pushArray(arr, arr2) { 
    arr.push.apply(arr, arr2); 
} 

... или добавить его в Array «s прототип:

Array.prototype.pushArray = function(arr) { 
    this.push.apply(this, arr); 
}; 

var newArray = []; 
newArray.pushArray(dataArray1); 
newArray.pushArray(dataArray2); 

... или эмулировать оригинал push(), разрешив несколько параметров с использованием того факта, что concat(), например push(), допускает множество параметров:

Array.prototype.pushArray = function() { 
    this.push.apply(this, this.concat.apply([], arguments)); 
}; 

var newArray = []; 
newArray.pushArray(dataArray1, dataArray2); 

Вот версия петли на основе последнего примера, подходит для больших массивов и всех основных браузерах, включая IE < = 8:

Array.prototype.pushArray = function() { 
    var toPush = this.concat.apply([], arguments); 
    for (var i = 0, len = toPush.length; i < len; ++i) { 
     this.push(toPush[i]); 
    } 
}; 
+7

примечание: 'newArray.push.apply (newArray, dataArray1); 'дает то же самое, что и' Array.prototype.push.applay (newArray, dataArra1); ' – 2013-07-05 11:02:46

+2

push.apply whas exacly, что я искал, thx –

+0

Большое спасибо за это решение! могу я спросить, есть ли что-то обратное? как удалить весь массив из другого? –

-4

вместо толчка() Функция Функция использования CONCAT для IE.Например,

var a=a.concat(a,new Array('amin')); 
-4

Вилла Руж является рабочий код и он работает отлично:

var els = document.getElementsByTagName('input'), i; 
var invnum = new Array(); 
var k = els.length; 
for(i = 0; i < k; i++){invnum.push(new Array(els[i].id,els[i].value))} 
-5

Самое простое:

var newArray = dataArray1.slice(0); 
+1

Это не касается проблемы в вопросе: объединение двух массивов. – frasertweedale

169

Я добавлю еще одно "будущее-доказательство" ответить

В ECMAScript 6 вы можете использовать spread operator:

var arr1 = [0, 1, 2]; 
var arr2 = [3, 4, 5]; 
arr1.push(...arr2); 

Оператор распространения еще не включен во все основные браузеры. Для текущей совместимости см. Это (постоянно обновляется) compatibility table.

Вы можете, однако, воспользоваться оператором спредов с Babel.js.

+2

Вы также можете использовать оператор распространения, если используете TypeScript. Если вы нацелитесь на ES5, он скомпилируется в 'newArray.apply (newArray, dataArray1)'. –

+0

MDN говорит, что это ** оператор распространения **: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator –

+2

@ KarelBílek у вас была правильная терминология в вашем первоначальном ответе, мое редактирование было просто пересмотром того, что вы написали в первую очередь. –

113

Обнаружили элегантный путь от MDN

var vegetables = ['parsnip', 'potato']; 
var moreVegs = ['celery', 'beetroot']; 

// Merge the second array into the first one 
// Equivalent to vegetables.push('celery', 'beetroot'); 
Array.prototype.push.apply(vegetables, moreVegs); 

console.log(vegetables); // ['parsnip', 'potato', 'celery', 'beetroot'] 

Или вы можете использовать spread operator особенность ES6:

let fruits = [ 'apple', 'banana']; 
const moreFruits = [ 'orange', 'plum' ]; 

fruits.push(...moreFruits); // ["apple", "banana", "orange", "plum"] 
+4

Это очень простое решение, которое мне нравится, потому что вы не ссылаетесь на новый массив в 'овощах', как если бы вы использовали метод' .concat', и цикл не требуется. –

3

Следующая кажется простейшим мне:

var newArray = dataArray1.slice(); 
newArray.push.apply(newArray, dataArray2); 

как " push "принимает переменное количество аргументов, вы можете использовать apply метод функции push для нажатия всех элементов другого массива. Он конструирует вызов для нажатия с использованием его первого аргумента (здесь здесь «newArray») как «this» и элементов массива в качестве остальных аргументов.

slice в первом выражении получает копию первого массива, поэтому вы не изменяете его.

5

С JavaScript ES6 вы можете использовать оператор ... как оператор спреда, который по существу преобразует массив в значения. Затем вы можете сделать что-то вроде этого:

var myArray = [1,2,3,4,5]; 
var moreData = [6,7,8,9,10]; 

myArray = [ 
    ...myArray, 
    ...moreData, 
]; 

Хотя синтаксис краткий, я не знаю, как это работает внутри и какие последствия производительности находятся на больших массивах.

+1

Если вы посмотрите на [как столпотворение преобразует его] (http://babeljs.io/repl/#?babili=false&browsers=&build=&builtIns=false&code_lz=MYewdgzgLgBAhgJwQRhgXhgbQOTgKbYA0M2UA7iNgLoDcAUKJLIggEzpakAWCeBx2AGYgArgmr06LZADoADiIhcAFDLUtWAShpA&debug=false&circleciRepo=&evaluate=false&lineWrap=true&presets=es2015%2Creact% 2Cstage-2 & prettier = false & target = & version = 6.26.0), вы увидите, что это не должно быть медленнее, чем использование метода Array.push.apply. –

4

Функция ниже не имеет проблемы с длиной массивов и работает лучше, чем все предлагаемые решения:

function pushArray(list, other) { 
    var len = other.length; 
    var start = list.length; 
    list.length = start + len; 
    for (var i = 0; i < len; i++ , start++) { 
     list[start] = other[i]; 
    } 
} 

, к сожалению, jspref отказывается принять мои представления, так вот они результаты, используя тест ,JS

 Name   | ops/sec | ± % | runs sampled 
for loop and push  |  177506 | 0.92 | 63 
Push Apply    |  234280 | 0.77 | 66 
spread operator   |  259725 | 0.40 | 67 
set length and for loop |  284223 | 0.41 | 66 

где

для контура и толчка:

for (var i = 0, l = source.length; i < l; i++) { 
     target.push(source[i]); 
    } 

Нажмите Применить:

target.push.apply(target, source); 

спреда оператора:

target.push(...source); 

и, наконец, «заданная длина и цикл» - это функция выше

0

У нас есть два массива a и b. код, который здесь представляет собой массив, вводится в массив b.

let a = [2, 4, 6, 8, 9, 15] 

function transform(a) { 
    let b = ['4', '16', '64'] 
    a.forEach(function(e) { 
     b.push(e.toString()); 
    }); 
    return b; 
} 

transform(a) 

[ '4', '16', '64', '2', '4', '6', '8', '9', '15' ] 
+0

Пожалуйста, не просто отправьте код в качестве ответа. Объясните, что делает код и как он решает проблему. –

5

Существует несколько ответов, говорящих о Array.prototype.push.apply. Вот наглядный пример:

var dataArray1 = [1, 2]; 
 
var dataArray2 = [3, 4, 5]; 
 
var newArray = [ ]; 
 
Array.prototype.push.apply(newArray, dataArray1); // newArray = [1, 2] 
 
Array.prototype.push.apply(newArray, dataArray2); // newArray = [1, 2, 3, 4, 5] 
 
console.log(JSON.stringify(newArray)); // Outputs: [1, 2, 3, 4, 5]

Если у вас есть ES6 синтаксис:

var dataArray1 = [1, 2]; 
 
var dataArray2 = [3, 4, 5]; 
 
var newArray = [ ]; 
 
newArray.push(...dataArray1); // newArray = [1, 2] 
 
newArray.push(...dataArray2); // newArray = [1, 2, 3, 4, 5] 
 
console.log(JSON.stringify(newArray)); // Outputs: [1, 2, 3, 4, 5]

Смежные вопросы