Перетворення об'єкта JS в масив за допомогою jQuery


417

Мій додаток створює об’єкт JavaScript, наприклад:

myObj= {1:[Array-Data], 2:[Array-Data]}

Але мені потрібен цей об’єкт як масив.

array[1]:[Array-Data]
array[2]:[Array-Data]

Тому я спробував перетворити цей об’єкт у масив шляхом ітерації $.eachчерез об’єкт та додавання елемента до масиву:

x=[]
$.each(myObj, function(i,n) {
    x.push(n);});

Чи є кращий спосіб перетворення об’єкта в масив чи, можливо, функцію?


1
Чи повинні індекси масиву збігатися з ключами в оригінальному об'єкті? Перший індекс у масиві завжди дорівнює 0, але ваш власний код та більшість відповідей (включаючи прийнятий), здається, ігнорують його; все-таки ви повернули мою редагування до бажаного результату.
Імре

1
Так, ви маєте рацію: перший елемент Array починається з 0. Але я відмінив ваше редагування, оскільки в моїх очах не було послідовним зробити цей приклад максимально простим, оскільки зміна myObj= {1:[Array-Data]на myObj= {0:[Array-Data]не було частиною вашої редагування (як я пам'ятаю правильно)
The Bndr

3
Використовуйте команду jQuery $ .makeArray (obj) для цієї api.jquery.com/jQuery.makeArray
DevlshOne

@DevlshOne в наданій документації сказано: "Перетворіть об’єкт jQuery в масив", я не думаю, що це відповідає питанню ОП
Алекс

Відповіді:


429
var myObj = {
    1: [1, 2, 3],
    2: [4, 5, 6]
};

var array = $.map(myObj, function(value, index) {
    return [value];
});


console.log(array);

Вихід:

[[1, 2, 3], [4, 5, 6]]

8
@Dogbert, будь ласка, чи можете ви пояснити $.map? Кожен пошук, який я намагаюся здійснити на цьому, виявляє безліч посилань на jQuery або метод масивів карт.
кранток

21
D'oh! Ігноруй мій коментар. Я не помітив тег jQuery з цього питання.
кранток

8
чи є спосіб підтримувати ключі в новому масиві? у кожній відповіді на веб-сайті, що я бачу, не вистачає перетворення ключів.
TD_Nijboer

55
Ви також можете це зробити без jQuery: Object.keys (myObject) .map (функція (val) {return [val]});
Кріс Еріксон

3
@TD_Nijboer Так, використовуйте value.key = index; return [value];замістьreturn [value];
Simon Arnold

742

Якщо ви шукаєте функціональний підхід:

var obj = {1: 11, 2: 22};
var arr = Object.keys(obj).map(function (key) { return obj[key]; });

Призводить до:

[11, 22]

Те саме з функцією стрілки ES6:

Object.keys(obj).map(key => obj[key])

З ES7 ви зможете використовувати Object.valuesзамість цього ( більше інформації ):

var arr = Object.values(obj);

Або якщо ви вже використовуєте Underscore / Lo-Dash:

var arr = _.values(obj)


3
Незадоволений найкращою відповіддю, я щойно написав цю майже точну функцію, повернувся, щоб опублікувати її як відповідь, прокрутив униз, побачив 170. Зрозумів, чоловіче Якби я не здався, я б не мав думати :) Це має бути вгорі. OP pls вибрати як відповідь.
j03m

1
для тих, для кого це не очевидно, ключі не повинні бути послідовними (тобто в цьому прикладі вони є 1 і 2 - але вони так само можуть бути рядковим ключем або непослідовним номером
Simon_Weaver

Для першого абзацу коду я пропускаю крапку з двокрапкою. Не знаю чому.
JohnnyBizzle

@JohnnyBizzle Я думаю, що вашому лінеру потрібно написати "return obj [key];" з крапкою з комою в кінці. JavaScript, хоча.
Джоель Річард

30

Я думаю, ви можете використовувати, for inале перевіряючи, чи властивість не інерується

myObj= {1:[Array-Data], 2:[Array-Data]}
var arr =[];
for( var i in myObj ) {
    if (myObj.hasOwnProperty(i)){
       arr.push(myObj[i]);
    }
}

EDIT - якщо ви хочете, ви також можете зберігати індекси свого об'єкта, але ви повинні перевірити, чи є вони числовими (і ви отримаєте невизначені значення для відсутніх індексів:

function isNumber(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

myObj= {1:[1,2], 2:[3,4]}
var arr =[];
for( var i in myObj ) {
    if (myObj.hasOwnProperty(i)){
        if (isNumber(i)){
            arr[i] = myObj[i];
        }else{
          arr.push(myObj[i]);
        }
    }
}

1
Ви повинні були перевірити код. $.mapсплющується Array-Data.
Марко Думіч

ти маєш рацію, я не перевіряв це з масивом, і карта згладжує його! я змінив відповідь
Нікола Пелучетті

@Nicola Peluchetti $ .makeArray () звучить добре, але це не те, що я шукав, тому що він просто ставить об'єкт до елемента масиву: [{1:[Array-Data], 2:[Array-Data]}]І $.map()також не виглядає успішним. Здається, що всі дані Sub-Array об'єднані в один масив. array.lengthповинен повернути 2 (тому що існує 2 елементи), але він повертає 67, що є кількістю всіх елементів у всіх ["масив-дані"].
Бндр

@The Bndr я опублікував інше рішення, але ви можете використовувати карту, як запропонував dogbert
Nicola Peluchetti

Я думаю, ви повинні чітко вказати індекс масиву ... як, наприклад, arr[+i] = myObj[i];тому, що (i) for(...in...)не гарантується повернення властивостей у будь-якому порядку (ii) у прикладі OP властивості починаються з 1, а не 0.
Salman A

30

Просто робіть

Object.values(obj);

Це все!


11
Object.values ​​- це метод ES2017, який не підтримується в Safari, IE, Node 6.
Phil Ricketts

25

Якщо ви знаєте максимальний індекс у вашому об’єкті, ви можете зробити наступне:

var myObj = {
    1: ['c', 'd'],
    2: ['a', 'b']
  },
  myArr;

myObj.length = 3; //max index + 1
myArr = Array.prototype.slice.apply(myObj);
console.log(myArr); //[undefined, ['c', 'd'], ['a', 'b']]


1
Було б набагато краще, щоб код, який генерує об'єкт, також встановив довжину або дійсно зробив його масивом в першу чергу. Я не сподіваюся, що це можливе, тому ця відповідь для мене не корисна.
user2000095-tim

myObj.length = Object.keys(myObj).length
лисини

19

Оскільки ES5 Object.keys () повертає масив, що містить властивості, визначені безпосередньо на об'єкті (виключаючи властивості, визначені в ланцюзі прототипу):

Object.keys(yourObject).map(function(key){ return yourObject[key] });

ES6 робить це на крок далі за допомогою стрілочних функцій:

Object.keys(yourObject).map(key => yourObject[key]);

1
Для поточного ES5 (хоча мені подобається ES6): Object.keys (yourObject) .map (функція (клавіша) {return yourObject [key]});
Давид Зоріхта

18

На сьогоднішній день існує простий спосіб зробити це: Object.values ​​() .

var myObj = {
    1: [1, 2, 3],
    2: [4, 5, 6]
};

console.log(Object.values(myObj));

Вихід:

[[1, 2, 3], [4, 5, 6]]

Для цього не потрібен jQuery, це визначено в ECMAScript 2017.
Його підтримує кожен сучасний браузер (забудьте IE).


якщо я роблю щось на кшталт, var state = { ingredient: { salad: 1, bacon: 1, } }а потім var HariOm = Object.values(state);за console.log(typeof HariOM)ним відображається тип як об'єкт. Чи не повинен він відображати його як масив?
iRohitBhatia

Це абсолютно нормально, перевірте посилання тут: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… - Ви можете використовуватиArray.isArray(HariOM)
Stopi

16

Найкращим методом було б використання лише функції javascript:

var myArr = Array.prototype.slice.call(myObj, 0);

@Qwerty який браузер?
тест30

Хром. Тестувавvar myObj = {1:[1,2,3],2:[4,5,6]};
Qwerty

Зауважте, що цей метод працює для перетворення "схожих на масив об'єктів", тобто вони повинні мати властивість "length" і перераховані властивості, що рахуються від 0. Отже, щоб приклад @ Qwerty працював, спробуйте це: {0: [1 , 2,3], 1: [4,5,6], довжина: 2}. Експериментуйте зі значеннями індексу та значеннями довжини, це трохи поблажливіше. Ось добре прочитане на тему: nfriedly.com/techblog/2009/06/… Пропустити вниз до "Об'єктів, подібних до масиву".
Метт

15
x = [];
for( var i in myObj ) {
    x[i] = myObj[i];
}

10
Ви повинні використовувати push, інакше ви можете створити об’єкт
Nicola Peluchetti

Можливо, це якась краща сила для введення індексу. var bbb = {'1': 'a', '3': 'b'}; var x = []; for (var i in bbb) { x[parseInt(i)] = bbb[i];} console.log(x);
tres.14159



6

Вирішення дуже просте

var my_obj = {1:[Array-Data], 2:[Array-Data]}
Object.keys(my_obj).map(function(property_name){ 
    return my_obj[property_name]; 
});


3

Fiddle Demo

Розширення на відповідь bjornd .

var myObj = {
    1: [1, [2], 3],
    2: [4, 5, [6]]
}, count = 0,
    i;
//count the JavaScript object length supporting IE < 9 also
for (i in myObj) {
    if (myObj.hasOwnProperty(i)) {
        count++;
    }
}
//count = Object.keys(myObj).length;// but not support IE < 9
myObj.length = count + 1; //max index + 1
myArr = Array.prototype.slice.apply(myObj);
console.log(myArr);


Довідково

Array.prototype.slice ()

Function.prototype.apply ()

Object.prototype.hasOwnProperty ()

Object.keys ()


Я можу помилятися, але чи краще для myObj бути численним, починаючи з 0? Крім того, мені здається, що там у нас є проблеми, де був би наш масив: [undefined, [1, [2], 3]] (Перша частина не визначена, тому що вона не знаходить myObj ['0'] а остання частина myObj ['2'] викидається, тому що після прочитання. довжини вона зупиняється на myObj ['1']?
Алекс Вернер,

2

Якщо ви хочете зберегти ім'я властивостей об'єкта як значення. Приклад:

var fields = {
    Name: { type: 'string', maxLength: 50 },
    Age: { type: 'number', minValue: 0 }
}

Використовуйте Object.keys(), Array.map()і Object.assign():

var columns = Object.keys( fields ).map( p => Object.assign( fields[p], {field:p} ) )

Результат:

[ { field: 'Name', type: 'string', maxLength: 50 }, 
  { field: 'Age', type: 'number', minValue: 0 } ]

Пояснення:

Object.keys()перераховує всі властивості джерела; .map()застосовує =>функцію до кожного властивості та повертає масив; Object.assign()об'єднує назву та значення для кожного ресурсу.


1

Я зробив спеціальну функцію:

    Object.prototype.toArray=function(){
    var arr=new Array();
    for( var i in this ) {
        if (this.hasOwnProperty(i)){
            arr.push(this[i]);
        }
    }
    return arr;
};

0

Після деяких тестів, тут є загальний об'єкт для перетворення функцій перетворювача:

У вас є об'єкт:

var obj = {
    some_key_1: "some_value_1"
    some_key_2: "some_value_2"
};

Функція:

function ObjectToArray(o)
{
    var k = Object.getOwnPropertyNames(o);
    var v = Object.values(o);

    var c = function(l)
    {
        this.k = [];
        this.v = [];
        this.length = l;
    };

    var r = new c(k.length);

    for (var i = 0; i < k.length; i++)
    {
        r.k[i] = k[i];
        r.v[i] = v[i];
    }

    return r;
}

Використання функції:

var arr = ObjectToArray(obj);

Ви отримуєте:

arr {
    key: [
        "some_key_1",
        "some_key_2"
    ],
    value: [
        "some_value_1",
        "some_value_2"
    ],
    length: 2
}

Тоді ви можете досягти всіх клавіш і значень, таких як:

for (var i = 0; i < arr.length; i++)
{
    console.log(arr.key[i] + " = " + arr.value[i]);
}

Результат у консолі:

some_key_1 = some_value_1
some_key_2 = some_value_2

Редагувати:

Або у формі прототипу:

Object.prototype.objectToArray = function()
{
    if (
        typeof this != 'object' ||
        typeof this.length != "undefined"
    ) {
        return false;
    }

    var k = Object.getOwnPropertyNames(this);
    var v = Object.values(this);

    var c = function(l)
    {
        this.k = [];
        this.v = [];
        this.length = l;
    };

    var r = new c(k.length);

    for (var i = 0; i < k.length; i++)
    {
        r.k[i] = k[i];
        r.v[i] = v[i];
    }

    return r;
};

А потім використовуйте:

console.log(obj.objectToArray);

0

Ви можете створити просту функцію для перетворення з objectна array, щось подібне може зробити роботу для вас, використовуючи чистий javascript:

var objectToArray = function(obj) {
  var arr = [];
  if ('object' !== typeof obj || 'undefined' === typeof obj || Array.isArray(obj)) {
    return obj;
  } else {
    Object.keys(obj).map(x=>arr.push(obj[x]));
  }
  return arr;
};

або цей:

var objectToArray = function(obj) {
  var arr =[];
  for(let o in obj) {
    if (obj.hasOwnProperty(o)) {
      arr.push(obj[o]);
    }
  }
  return arr;
};

і зателефонуйте та скористайтеся функцією, як показано нижче:

var obj = {1:'a', 2:'b', 3:'c', 4:'d', 5:'e'};
objectToArray(obj); // return ["a", "b", "c", "d", "e"]

Також у майбутньому у нас з’явиться щось, що називається Object.values(obj), схоже на Object.keys(obj)яке поверне всі властивості для вас як масив, але ще не підтримується у багатьох браузерах ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.