Jak przekonwertować Object {} na Array [] par klucz-wartość w JavaScript

243

Chcę przekonwertować taki obiekt:

{"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}

w tablicę par klucz-wartość, takich jak to:

[[1,5],[2,7],[3,0],[4,0]...].

Jak przekonwertować obiekt na tablicę par klucz-wartość w JavaScript?

Soptareanu Alex
źródło

Odpowiedzi:

428

Możesz użyć Object.keys()i map()do tego

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result = Object.keys(obj).map(function(key) {
  return [Number(key), obj[key]];
});

console.log(result);

Nenad Vracar
źródło
6
@blvckasvp Czy używasz liczb jako kluczy? Jeśli nie, próba konwersji klucza na numer zakończy się niepowodzeniem i NaNzamiast tego wróci . Jeśli chcesz używać ciągów jako kluczy, zmień zwrot z [Number(key), obj[key]]na [key, obj[key]]lub skorzystaj z Object.entriessugestii @Pila w odpowiedzi
scottbot95
123

Najlepszym sposobem jest:

var obj ={"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10"‌​:0,"11":0,"12":0} 
Object.entries(obj);

Dzwonienie entries, jak pokazano tutaj, zwróci [key, value]pary, zgodnie z prośbą pytającego.

Alternatywnie możesz zadzwonić Object.values(obj), co zwróci tylko wartości.

Piła
źródło
6
Drodzy programiści, proszę przejrzeć tabelę kompatybilności ECMA przed przyjęciem tych przyjemnych funkcji, które są kompatybilne tylko z przeglądarkami wydanymi kilka minut temu.
andreszs,
8
@andreszs Zobacz tabelę Czy mogę używać , jeśli nie masz nic przeciwko rezygnacji z obsługi IE (a w 2019 roku mam nadzieję, że dla twojego zdrowia psychicznego tak naprawdę tego nie robisz), to jesteś całkiem dobry. FF 47 pochodzi z czerwca 2016 r., A Chrome 54 - z października tego samego roku, Edge 14 sierpnia. Nie dokładnie kilka minut temu.
Kyll,
FYI: Object.entries zwróci [klucz, wartość], ale klucz będzie ciągiem, wartość będzie się różnić.
SHAHBAZ,
62

Object.entries()zwraca tablicę, której elementy są tablicami odpowiadającymi wymiennym [key, value]parom właściwości znalezionym bezpośrednio na object. Kolejność właściwości jest taka sama, jak podana przez ręczne zapętlenie wartości właściwości obiektu.

- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries#Description

Że Object.entriesfunkcja zwraca niemal dokładna wyjście pytasz za wyjątkiem klawiszy są ciągi zamiast numerów.

const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};

console.log(Object.entries(obj));

Jeśli potrzebujesz, aby klucze były cyframi, możesz odwzorować wynik na nową tablicę z funkcją wywołania zwrotnego, która zastępuje klucz w każdej parze liczbą wymuszoną z niego.

const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};

const toNumericPairs = input => {
    const entries = Object.entries(input);
    return entries.map(entry => Object.assign(entry, { 0: +entry[0] }));
}

console.log(toNumericPairs(obj));

Używam funkcji strzałki i Object.assigndo wywołania zwrotnego mapy w powyższym przykładzie, dzięki czemu mogę zachować ją w jednej instrukcji, wykorzystując fakt, że Object.assignzwraca obiekt, do którego jest przypisany, a wartość zwracana przez funkcję pojedynczej instrukcji jest wynikiem instrukcji.

Jest to równoważne z:

entry => {
    entry[0] = +entry[0];
    return entry;
}

Jak wspomniano w komentarzach @TravisClarke, funkcję mapy można skrócić do:

entry => [ +entry[0], entry[1] ]

Jednak stworzyłoby to nową tablicę dla każdej pary klucz-wartość, zamiast modyfikować istniejącą tablicę w miejscu, podwajając liczbę utworzonych tablic pary klucz-wartość. Chociaż tablica oryginalnych wpisów jest nadal dostępna, to i jej wpisy nie będą usuwane.

Teraz, mimo że nasza metoda lokalna nadal używa dwóch tablic, które przechowują pary klucz-wartość (tablice wejściowa i wyjściowa), całkowita liczba tablic zmienia się tylko o jeden. Tablice wejściowe i wyjściowe nie są tak naprawdę wypełnione tablicami, ale raczej referencje do tablic i te referencje zajmują mało miejsca w pamięci.

  • Modyfikacja każdej pary klucz-wartość w miejscu powoduje nieznaczny wzrost pamięci, ale wymaga wpisania kilku dodatkowych znaków.
  • Utworzenie nowej tablicy dla każdej pary klucz-wartość powoduje podwojenie wymaganej ilości pamięci, ale wymaga wpisania kilku mniej znaków.

Możesz pójść o krok dalej i całkowicie wyeliminować wzrost, modyfikując tablicę wpisów w miejscu zamiast mapować ją na nową tablicę:

const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};

const toNumericPairs = input => {
  const entries = Object.entries(obj);
  entries.forEach(entry => entry[0] = +entry[0]);
  return entries;
}

console.log(toNumericPairs(obj));


źródło
1
Lubię funkcjonalne podejście. Jako krótsza alternatywa:Object.entries(obj).map(e => [+e[0], e[1]]);
Travis Clarke
21

Podsumowując niektóre z tych odpowiedzi teraz w 2018 r., Gdzie ES6 jest standardem.

Począwszy od obiektu:

let const={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
  • Po prostu ślepo pobieramy wartości z tablicy, nie przejmuj się kluczami:

const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.values(obj));
//[9,8,7,6,5,4,3,2,1,0,5]

  • Proste pobieranie par w tablicy:

const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj));
//[["1",9],["2",8],["3",7],["4",6],["5",5],["6",4],["7",3],["8",2],["9",1],["10",0],["12",5]]

  • Taki sam jak poprzedni, ale z klawiszami numerycznymi na każdej parze:

const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj).map(([k,v])=>[+k,v]));
//[[1,9],[2,8],[3,7],[4,6],[5,5],[6,4],[7,3],[8,2],[9,1],[10,0],[12,5]]

  • Używanie właściwości object jako klucza do nowej tablicy (może tworzyć rzadkie tablice):

const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj).reduce((ini,[k,v])=>(ini[k]=v,ini),[]));
//[undefined,9,8,7,6,5,4,3,2,1,0,undefined,5]

Ta ostatnia metoda może również reorganizować kolejność tablic w zależności od wartości kluczy. Czasami może to być pożądane zachowanie (czasem nie). Ale zaletą jest teraz to, że wartości są indeksowane w odpowiednim gnieździe tablicowym, co jest niezbędne i trywialne do wyszukiwania na nim.

  • Mapa zamiast tablicy

Na koniec (nie jest częścią pierwotnego pytania, ale dla kompletności), jeśli chcesz łatwo wyszukiwać za pomocą klucza lub wartości, ale nie chcesz rzadkich tablic, żadnych duplikatów i ponownego zamawiania bez konieczności konwersji na klucze numeryczne ( nawet może uzyskać dostęp do bardzo złożonych kluczy), wtedy tablica (lub obiekt) nie jest tym, czego potrzebujesz. Ja polecam Mapzamiast:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

let r=new Map(Object.entries(obj));
r.get("4"); //6
r.has(8); //true
CarlosH.
źródło
2
Czwarty punkt i dalej jest całkowicie nieistotny dla pytania, a reszta twojej odpowiedzi podsumowuje tylko trzy najważniejsze odpowiedzi tutaj. Ta odpowiedź nie wnosi nic do dyskusji, która jeszcze tu nie była lub nie jest całkowicie nieistotna.
Tak, jako stan pierwszego wiersza, jest to podsumowanie odpowiedzi, a następnie zaktualizuj je, aby używały nowoczesnych technik ES6 zamiast pełnych funkcji dmuchania. Czwarta odpowiedź jest przydatna, gdy przenosisz tablice JSON z języka obsługującego tablice asocjacyjne (np. PHP).
CarlosH.
Wszystkie metody przedstawione tutaj zostały już przedstawione w formie zwykłej w dwóch z trzech najważniejszych odpowiedzi, nie są one w funkcjach, więc nie wiem, o czym tu jesteś. Co do czwartego, jak powiedziałem, jest to całkowicie nieistotne dla postawionego pytania. Może dotyczyć innego pytania, ale nie tego. Niezależnie od tego, JSON jest JSON, niezależnie od tego, czy jest tworzony przy użyciu PHP, JavaScript czy Haskell.
18

Jeszcze jedno rozwiązanie, jeśli Object.entriesnie zadziała dla Ciebie.

const obj = {
      '1': 29,
      '2': 42
    };
const arr = Array.from(Object.keys(obj), k=>[`${k}`, obj[k]]);
console.log(arr);

bigh_29
źródło
1
To zadziałało dla mnie. Wystąpił problem polegający na tym, że podczas importowania JSON dodano indeksy, które uniemożliwiały użycie pętli Angulars ngFor. Spowodowało to usunięcie indeksów przy jednoczesnym zachowaniu struktury.
RAC
@RAC +1 za używanie „indeksów” zamiast „indeksów”. Rozpocznij archaiczne (tj. Arbitralne i pozbawione znaczenia dewiacje) angielskie tradycje!
Venryx
12

W Ecmascript 6

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};

var res = Object.entries(obj);

console.log(res);

skrzypce

Nageshwar Reddy Pandem
źródło
Nie jestem pewien, dlaczego zostało to zanegowane, działało idealnie
sMyles
1
Nie przegłosowałem, ale zauważ, że ta .map((value)=>(value))część jest bez znaczenia - po prostu zwraca tablicę wejściową dokładnie równoważną do tej uzyskanej z Object.entries(obj)wywołania.
Venryx
8

Zastosowanie Object.keysi Array#mapmetody.

var obj = {
  "1": 5,
  "2": 7,
  "3": 0,
  "4": 0,
  "5": 0,
  "6": 0,
  "7": 0,
  "8": 0,
  "9": 0,
  "10": 0,
  "11": 0,
  "12": 0
};
// get all object property names
var res = Object.keys(obj)
  // iterate over them and generate the array
  .map(function(k) {
    // generate the array element 
    return [+k, obj[k]];
  });

console.log(res);

Pranav C. Balan
źródło
7

Użyj, Object.entriesaby uzyskać każdy element obiektu w key & valueformacie, a następnie mapprzez niego w następujący sposób:

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}

var res = Object.entries(obj).map(([k, v]) => ([Number(k), v]));

console.log(res);

Ale jeśli masz pewność, że klucze będą w kolejności progresywnej, możesz użyć Object.valuesi Array#mapzrobić coś takiego:

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}; 

                        // idx is the index, you can use any logic to increment it (starts from 0)
let result = Object.values(obj).map((e, idx) => ([++idx, e]));

console.log(result);

Czarnobrody
źródło
5

Jeśli używasz lodash, może to być tak proste:

var arr = _.values(obj);
Adam Boostani
źródło
5

Z lodash, oprócz odpowiedzi podanej powyżej, możesz również mieć klucz w tablicy wyjściowej.

Bez kluczy obiektów w tablicy wyjściowej

dla:

const array = _.values(obj);

Jeśli obj jest następujące:

{ art”: { id: 1,  title: aaaa }, fiction”: { id: 22,  title: 7777”} }

Zatem tablica będzie:

[ { id: 1, title: aaaa }, { id: 22, title: 7777 } ]

Z kluczami obiektowymi w tablicy wyjściowej

Jeśli zamiast tego napiszesz („gatunek” to wybrany przez Ciebie ciąg):

const array= _.map(obj, (val, id) => {
    return { ...val, genre: key };
  });

Dostaniesz:

[ 
  { id: 1, title: aaaa , genre: art”}, 
  { id: 22, title: 7777”, genre: fiction }
]
Yossi
źródło
4

Sugerowałbym to najprostsze rozwiązanie Object.entries()

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result =Object.entries(obj)

console.log(result);

Irony Stack
źródło
1

Możesz użyć Object.values([]), możesz potrzebować tego wypełnienia, jeśli jeszcze tego nie zrobiłeś:

const objectToValuesPolyfill = (object) => {
  return Object.keys(object).map(key => object[key]);
};
Object.values = Object.values || objectToValuesPolyfill;

https://stackoverflow.com/a/54822153/846348

Następnie możesz po prostu zrobić:

var object = {1: 'hello', 2: 'world'};
var array = Object.values(object);

Pamiętaj tylko, że tablice w js mogą używać tylko klawiszy numerycznych, więc jeśli użyjesz czegoś innego w obiekcie, wówczas staną się one „0,1,2 ... x”

Przydatne może być usunięcie duplikatów, na przykład, jeśli masz unikalny klucz.

var obj = {};
object[uniqueKey] = '...';
OZZIE
źródło
0

Użyj dla w

var obj = { "10":5, "2":7, "3":0, "4":0, "5":0, "6":0, "7":0,
            "8":0, "9":0, "10":0, "11":0, "12":0 };

var objectToArray = function(obj) {
    var _arr = [];

    for (var key in obj) {
        _arr.push([key, obj[key]]);
    }
    return _arr;
}

console.log(objectToArray(obj));
wkyniston
źródło
0

Rekurencyjny obiekt konwersji na tablicę

function is_object(mixed_var) {
    if (mixed_var instanceof Array) {
        return false;
    } else {
        return (mixed_var !== null) && (typeof( mixed_var ) == 'object');
    }
}


function objectToArray(obj) {
    var array = [], tempObject;
    for (var key in obj) {

        tempObject = obj[key];

        if (is_object(obj[key])) {
            tempObject = objectToArray(obj[key]);
        }
        array[key] = tempObject;
    }
    return array;
}
Marina Lebiediewa
źródło
0

Możemy zmienić Number na Type String dla Key jak poniżej:

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result = Object.keys(obj).map(function(key) {
  return [String(key), obj[key]];
});
    
console.log(result);

Nagnath Mungade
źródło
0

To jest moje rozwiązanie, mam ten sam problem i wygląda na to, że to rozwiązanie działa dla mnie.

yourObj = [].concat(yourObj);
Qui-Gon Jinn
źródło
0

Oto moja prosta implementacja barebone:

let obj = {
  "1": 5,
  "2": 7,
  "3": 0,
  "4": 0,
  "5": 0,
  "6": 0,
  "7": 0,
  "8": 0,
  "9": 0,
  "10": 0,
  "11": 0,
  "12": 0
};    

const objectToArray = obj => {
      let sol = [];
      for (key in obj) {
        sol.push([key, obj[key]]);
      }
      return sol;
    };

objectToArray(obj)
Ketan Ramteke
źródło
0

Proste rozwiązanie

`

var result = Object.keys(records).map(function (value) {
         return { [value]: records[value] };
});
console.log(result);

Folorunso
źródło