Jak uzyskać podzbiór właściwości obiektu javascript


424

Powiedz, że mam przedmiot:

elmo = { 
  color: 'red',
  annoying: true,
  height: 'unknown',
  meta: { one: '1', two: '2'}
};

Chcę zrobić nowy obiekt z podzbiorem jego właściwości.

 // pseudo code
 subset = elmo.slice('color', 'height')

 //=> { color: 'red', height: 'unknown' }

Jak mogę to osiągnąć?


2
Biblioteka Underscore ma wiele takich funkcji pomocniczych, sprawdź to: underscorejs.org/#pick
— Stefan

4
Tak myślałem emo.slicena pierwszy rzut oka.
— Bill Criswell

1
Po namyśle ... Nie utworzę podzbioru ...
— Andrew

Odpowiedzi:


673

Używanie destrukcji obiektów i skrótów własności

const object = { a: 5, b: 6, c: 7  };
const picked = (({ a, c }) => ({ a, c }))(object);

console.log(picked); // { a: 5, c: 7 }


Od Philipp Kewisch:

Jest to tak naprawdę tylko anonimowa funkcja wywoływana natychmiast. Wszystko to można znaleźć na stronie Przydziału Destrukturyzacji w MDN. Oto rozwinięta forma

let unwrap = ({a, c}) => ({a, c});

let unwrap2 = function({a, c}) { return { a, c }; };

let picked = unwrap({ a: 5, b: 6, c: 7 });

let picked2 = unwrap2({a: 5, b: 6, c: 7})

console.log(picked)
console.log(picked2)


37
Jak dowiedziałeś się, jak to zrobić? Nigdzie w żadnych dokumentach ani artykułach, które widziałem (w tym MDN), nie pokazuje składni strzałki używanej w Object Destrukturyzacji. To bardzo miło wiedzieć.
— papiro

52
Jest to tak naprawdę tylko anonimowa funkcja wywoływana natychmiast. Wszystko to można znaleźć na stronie Przydziału Destrukturyzacji w MDN. Oto rozwinięta forma: let unwrap = ({a, c}) => ({a, c}); let unwrap2 = function({a, c}) { return { a, c }; }; let picked = unwrap({ a: 5, b: 6, c: 7 });
— Philipp Kewisch

8
czy istnieje sposób, aby zrobić to dynamicznie z operatorem rozprzestrzeniania?
— Tom Sarduy,

4
@TomSarduy można użyć resztę, jeśli chcesz określić, które rekwizyty do usunięcia, np const { b, ...picked } = objectstworzyłoby pickedjak { a: 5, c: 7 }. Podałeś po prostu usunąć b. Twoja eslint prawdopodobnie będzie cię zirytowana za zadeklarowanie zmiennej, której nie używasz.
— Josh z Qaribou

24
Wadą tego rozwiązania jest to, że musisz dwukrotnie wpisać ciąg nazw atrybutów. Może to stanowić poważny problem w przypadkach, w których należy wybrać wiele atrybutów.
— Gershom

144

Proponuję rzucić okiem na Lodash ; ma wiele świetnych funkcji narzędziowych.

Na przykład pick()byłoby dokładnie to, czego szukasz:

var subset = _.pick(elmo, ['color', 'height']);

skrzypce


2
to samo dotyczy underscore.js
— Dan

1
Czy jest jakaś funkcja wykluczająca tylko niektóre pola zamiast wybierania? więc mam około 50 pól w moim Jsonie i chcę wszystko oprócz 2 pól.
— Shrikant Prabhu

7
tak! możesz użyć, _.omit(elmo, ['voice'])aby zwrócić wszystko, alevoice
— xavdid

w tym podejściu nie podoba mi się to, że umieszczasz nazwy pól w cudzysłowie, więc jest podatny na literówki, typowe refaktoryzacje, takie jak zmiana nazwy właściwości w twoim IDE, nie będą w stanie jej odebrać itp.
— Andy

117

Jeśli używasz ES6, istnieje bardzo zwięzły sposób na zrobienie tego za pomocą destrukcji. Destrukturyzacja pozwala łatwo dodawać do obiektów za pomocą rozkładówki, ale umożliwia także tworzenie obiektów podzbiorów w ten sam sposób.

const object = {
  a: 'a',
  b: 'b',
  c: 'c',
  d: 'd',
}

// Remove "c" and "d" fields from original object:
const {c, d, ...partialObject} = object;
const subset = {c, d};

console.log(partialObject) // => { a: 'a', b: 'b'}
console.log(subset) // => { c: 'c', d: 'd'};

6
działa to tylko w celu usunięcia pola, a nie wybrania znanego podzbioru? potencjalnie nieskończoną liczbę nieznanych pól do usunięcia, ale być może tego szukają niektórzy ludzie
— Alexander Mills

To prawda, ale może usunąć kilka znanych pól, które można następnie przypisać do nowego obiektu, dzięki czemu nadal wydaje się odpowiedni dla tego pytania. Dodano do odpowiedzi w celu dalszego zilustrowania.
— Lauren

1
Jest to zasadniczo to samo, co w odpowiedzi @ Ivana Nosova , chociaż wyjaśniono to tutaj w bardziej zrozumiały sposób
— icc97

81

Chociaż jest to trochę bardziej szczegółowe, możesz osiągnąć to, co wszyscy inni zalecili podkreślenie / lodash 2 lata temu, używając Array.prototype.reduce .

var subset = ['color', 'height'].reduce(function(o, k) { o[k] = elmo[k]; return o; }, {});

Takie podejście rozwiązuje to z drugiej strony: zamiast brać obiekt i przekazywać do niego nazwy właściwości, aby je wyodrębnić, weź tablicę nazw właściwości i zredukuj je do nowego obiektu.

Chociaż w najprostszym przypadku jest bardziej szczegółowe, oddzwonienie tutaj jest dość przydatne, ponieważ możesz łatwo spełnić niektóre typowe wymagania, np. Zmienić właściwość „color” na „color” na nowym obiekcie, spłaszczyć tablice itp. - dowolne z rzeczy, które musisz zrobić, otrzymując obiekt z jednej usługi / biblioteki i budując nowy obiekt potrzebny gdzie indziej. Podczas gdy podkreślenie / lodash to doskonałe, dobrze zaimplementowane biblioteki lib, jest to moje preferowane podejście, polegające na mniejszym uzależnieniu od dostawcy, i prostsze, bardziej spójne podejście, gdy moja logika budowania podzbiorów staje się bardziej złożona.

edycja: wersja es7 tego samego:

const subset = ['color', 'height'].reduce((a, e) => (a[e] = elmo[e], a), {});

edycja: Również dobry przykład curry! Niech funkcja „pick” zwróci inną funkcję.

const pick = (...props) => o => props.reduce((a, e) => ({ ...a, [e]: o[e] }), {});

Powyższe jest dość zbliżone do drugiej metody, z tą różnicą, że pozwala budować „próbnik” w locie. na przykład

pick('color', 'height')(elmo);

Szczególnie schludne w tym podejściu jest to, że możesz łatwo wprowadzić wybrane „typy” w dowolne funkcje, np . Array#map:

[elmo, grover, bigBird].map(pick('color', 'height'));
// [
//   { color: 'red', height: 'short' },
//   { color: 'blue', height: 'medium' },
//   { color: 'yellow', height: 'tall' },
// ]

3
es6 umożliwia jeszcze czystsze dzięki funkcjom strzałek, a powrót Object.assign (ponieważ przypisanie do właściwości obiektu zwraca wartość właściwości, ale Object.assign zwraca obiekt.)
— Josh z Qaribou

Kolejna uwaga es6: bardzo rzadko musisz tego już robić, ponieważ zazwyczaj po prostu niszczysz przypisanie lub argumenty. np. function showToy({ color, height }) {objąłby tylko to, czego potrzebujesz. reducePodejście głównie sens kiedy upraszczania obiektów dla serializacji.
— Josh z Qaribou

6
Ta wersja ES6 jest mniej wydajna, ponieważ tworzy kopię wszystkich właściwości przy każdej iteracji. Dokonuje operacji O (n) w O (n ^ 2). Odpowiednikiem pierwszego bloku kodu ES6 byłbyconst pick = (obj, props) => props.reduce((a, e) => (a[e] = obj[e], a), {});
— 4castle

@ 4castle tak, dobra rozmowa - nie ma sensu tak wiele iteracji. Lubię składnię przecinków - lepiej niż kilka zwrotów.
— Josh z Qaribou

1
@ShevchenkoViktor Właściwie użyłem tego podejścia w mojej oryginalnej wersji es6, ale zmieniłem to po komentarzu @ 4castle. Myślę, że rozkład jest bardziej przejrzysty, ale jest to ogromna różnica w przypadku większych obiektów w kodzie, które mogą z łatwością znajdować się na wąskim gardle (np. Opóźnienie renderowania danych zwróconych z fetch), dlatego polecam dodanie komentarza wyjaśniającego użycie operatora przecinka.
— Josh z Qaribou

45

Restrukturyzacja ES6

Składnia destrukcyjna pozwala na destrukcję i rekombinację obiektu, z parametrami funkcji lub zmiennymi.

Ograniczeniem jest to, że lista kluczy jest predefiniowana, nie można ich wymienić jako ciągów, jak wspomniano w pytaniu. Restrukturyzacja staje się bardziej skomplikowana, jeśli klucz nie jest alfanumeryczny, np foo_bar.

Minusem jest to, że wymaga to powielenia listy kluczy, skutkuje to pełnym kodem na wypadek, gdyby lista była długa. Ponieważ w tym przypadku destrukcja duplikuje składnię dosłowną obiektu, listę można skopiować i wkleić bez zmian.

Plusem jest to, że jest to wydajne rozwiązanie, które jest naturalne dla ES6.

IIFE

let subset = (({ foo, bar }) => ({ foo, bar }))(obj); // dupe ({ foo, bar })

Zmienne tymczasowe

let { foo, bar } = obj;
let subset = { foo, bar }; // dupe { foo, bar }

Lista ciągów

Dowolna lista wybranych kluczy składa się z ciągów znaków, zgodnie z wymaganiami pytania. Pozwala to nie predefiniować ich i używać zmiennych zawierających nazwy kluczy, takich jak pick(obj, 'foo', someKey, ...moreKeys).

Jedna linijka staje się krótsza z każdą edycją JS.

ES5

var subset = Object.keys(obj)
.filter(function (key) { 
  return ['foo', 'bar'].indexOf(key) >= 0;
})
.reduce(function (obj2, key) {
  obj2[key] = obj[key];
  return obj2;
}, {});

ES6

let subset = Object.keys(obj)
.filter(key => ['foo', 'bar'].indexOf(key) >= 0)
.reduce((obj2, key) => Object.assign(obj2, { [key]: obj[key] }), {});

Lub z przecinkiem:

let subset = Object.keys(obj)
.filter(key => ['foo', 'bar'].indexOf(key) >= 0)
.reduce((obj2, key) => (obj2[key] = obj[key], obj2), {});

ES2019

ECMAScript 2017 ma, Object.entriesa Array.prototype.includesECMAScript 2019 ma Object.fromEntries, mogą być wypełniane w razie potrzeby i ułatwiają zadanie:

let subset = Object.fromEntries(
  Object.entries(obj)
  .filter(([key]) => ['foo', 'bar'].includes(key))
)

Jednowierszowypick może być przepisany jako funkcja pomocnicza podobna do Lodash lub omitgdy lista kluczy jest przekazywana przez argumenty:

let pick = (obj, ...keys) => Object.fromEntries(
  Object.entries(obj)
  .filter(([key]) => keys.includes(key))
);

let subset = pick({ foo: 1, qux: 2 }, 'foo', 'bar'); // { foo: 1 }

Uwaga na temat brakujących kluczy

Główną różnicą między destrukcją a tradycyjną funkcją typu Lodash pickjest to, że destrukcja obejmuje nieistniejące wybrane klucze o undefinedwartości w podzbiorze:

(({ foo, bar }) => ({ foo, bar }))({ foo: 1 }) // { foo: 1, bar: undefined }

To zachowanie może być pożądane lub nie. Nie można go zmienić dla składni destrukcyjnej.

Chociaż pickmożna zmienić, aby uwzględnić brakujące klucze, iterując zamiast tego listę wybranych kluczy:

let inclusivePick = (obj, ...keys) => Object.fromEntries(
  keys.map(key => [key, obj[key]])
);

let subset = inclusivePick({ foo: 1, qux: 2 }, 'foo', 'bar'); // { foo: 1, bar: undefined }

11
Jaka szkoda, że ​​ta odpowiedź jest tak aktualna, a zatem nie zyskuje takiej ekspozycji, na jaką zasługuje. IMO powinna być przyjętą odpowiedzią na kompletność, prostotę, wszechstronność i sprawiedliwość. Zachowam wersję ES6 w mojej najbardziej użytecznej bibliotece fragmentów.
— VanAlbert

ES5 - „Błąd Uncaught ReferenceError: obj nie jest zdefiniowany”
— Nikhil Vartak

@NikhilVartak Oczekuje się, że objzmienna jest zmienną przechowującą obiekt. Jeśli nazwa zmiennej jest inna, użyj jej zamiast obj.
— Estus Flask

Mój błąd! Przeoczyłem Object.keys(obj). Senny.
— Nikhil Vartak

34

Nie ma nic takiego wbudowanego w bibliotekę podstawową, ale możesz to zrobić, używając restrukturyzacji obiektów ...

const {color, height} = sourceObject;
const newObject = {color, height};

Możesz także napisać funkcję narzędziową zrób to ...

const cloneAndPluck = function(sourceObject, keys) {
    const newObject = {};
    keys.forEach((obj, key) => { newObject[key] = sourceObject[key]; });
    return newObject;
};

const subset = cloneAndPluck(elmo, ["color", "height"]);

Biblioteki takie jak Lodash również mają _.pick().


1
świetnie, właśnie musiałem zmienić forEach na: keys.forEach (key => {newObject [key] = sourceObject [key];}) ;. Zaktualizuj komentarz, jeśli ma to sens.
— kandan

34

Dodaję tę odpowiedź, ponieważ żadna z odpowiedzi nie została użyta Comma operator.

Jest to bardzo łatwe destructuring assignmenti ,operatora

const object = { a: 5, b: 6, c: 7  };
const picked = ({a,c} = object, {a,c})

console.log(picked);

Z pewnym ulepszeniem przypisywania właściwości dynamicznych mogłoby to wyglądać następująco:


2
moje złe, nie wiem co zrobiłem wcześniej, że to nie działało, ale wydaje się, że działa
— ekkis

1
To najlepsze wyrażenie, jeśli chodzi o restrukturyzację
— Mohamed Allal

1
to rozwiązanie jest sprytne, ale nie działa w trybie ścisłym (tj 'use strict'.). Dostaję ReferenceError: a is not defined.
— kimbaudi

8
Zauważ, że to podejście zanieczyszcza obecny zakres dwiema zmiennymi ai c- uważaj, aby nie nadpisywać losowo zmiennych lokalnych lub globalnych w zależności od kontekstu. (Przyjęta odpowiedź pozwala uniknąć tego problemu poprzez użycie dwóch zmiennych lokalnych w funkcji wbudowanej, która po natychmiastowym wykonaniu nie wchodzi w zakres).
— mindplay.dk

2
Zanieczyszczenie przestrzeni nazw czyni to całkowicie niepraktycznym. Bardzo często występują już zmienne w zakresie, które pasują do właściwości obiektu, dlatego istnieje skrót skrótu + destrukcja. Bardzo prawdopodobne, że wysokość lub kolor są już zdefiniowane, jak w oryginalnym przykładzie.
— Josh z Qaribou

23

Jeszcze jedno rozwiązanie:

var subset = {
   color: elmo.color,
   height: elmo.height 
}

Wydaje mi się to bardziej czytelne niż jakakolwiek jak dotąd odpowiedź, ale może to tylko ja!


9
Wolę produktywność niż wymyślny, ale mylący kod, aw rzeczywistości inżynieria oprogramowania to zdecydowanie najbardziej czytelne i łatwe do utrzymania rozwiązanie.
— Janos

1
Tak, jednak dla mnie jedną z zalet stosowania destrukcji i skrótowej notacji jest to, że jest ona mniej podatna na błędy. Gdybym miał grosz za każdym razem, gdy błędnie skopiowałem i wkleiłem kod subset = {color: elmo.color, height: elmo.color}, musiałbym mieć przynajmniej ... cóż, może dziesięciocentówkę.
— JHH

Nie nazwałbym tego destrukcyjnym skrótem i mniej podatnym na błędy, ponieważ nie jest to OSUSZANIE
— gman

Musiałbym się zgodzić. Bez zanieczyszczania kontekstu niepożądanymi zmiennymi jest to zdecydowanie najbardziej czytelne rozwiązanie. Reszta wygląda na zbyt mylącą. Wolę rozumieć mój kod, gdy tylko na niego spojrzę.
— Andrew

11

Możesz także użyć Lodash .

var subset = _.pick(elmo ,'color', 'height');

Uzupełniając, powiedzmy, że masz tablicę „elmo”:

elmos = [{ 
      color: 'red',
      annoying: true,
      height: 'unknown',
      meta: { one: '1', two: '2'}
    },{ 
      color: 'blue',
      annoying: true,
      height: 'known',
      meta: { one: '1', two: '2'}
    },{ 
      color: 'yellow',
      annoying: false,
      height: 'unknown',
      meta: { one: '1', two: '2'}
    }
];

Jeśli chcesz tego samego zachowania, używając lodash, po prostu:

var subsets = _.map(elmos, function(elm) { return _.pick(elm, 'color', 'height'); });

10

Jak opisano w tym pytaniu, przekształcanie w zmienne o nazwach dynamicznych jest niemożliwe w JavaScript .

Aby dynamicznie ustawiać klucze , możesz użyć funkcji zmniejszania bez mutowania obiektu w następujący sposób:

const getSubset = (obj, ...keys) => keys.reduce((a, c) => ({ ...a, [c]: obj[c] }), {});

const elmo = { 
  color: 'red',
  annoying: true,
  height: 'unknown',
  meta: { one: '1', two: '2'}
}

const subset = getSubset(elmo, 'color', 'annoying')
console.log(subset)

Należy pamiętać, że tworzysz nowy obiekt przy każdej iteracji zamiast aktualizować pojedynczy klon. - mpen

poniżej znajduje się wersja wykorzystująca redukcję z pojedynczym klonem (aktualizacja wartości początkowej przekazana w celu zmniejszenia).

const getSubset = (obj, ...keys) => keys.reduce((acc, curr) => {
  acc[curr] = obj[curr]
  return acc
}, {})

const elmo = { 
  color: 'red',
  annoying: true,
  height: 'unknown',
  meta: { one: '1', two: '2'}
}

const subset = getSubset(elmo, 'annoying', 'height', 'meta')
console.log(subset)


1
Niesamowite! Przez chwilę rzuciło mi się, nie zdając sobie sprawy z tego, jak istotne są nawiasy kwadratowe [c]:. Zakładam, że w jakiś sposób powoduje to, że c jest postrzegane jako wartość zamiast nazwy właściwości. W każdym razie bardzo fajnie. +1
— John Fairbanks

Dzięki stary! To użycie jest jedną rzeczą, którą uwielbiam w JavaScript, która umożliwia ogólne funkcje bez użycia eval. Po prostu pozwala ustawić klucz dykta do zmiennej w czasie wykonywania. jeśli zdefiniujesz var key = „someKey”, możesz użyć go jako {[klucz]: „wartość”}, co daje {someKey: „wartość”}. Bardzo fajny.
— Muhammet Enginar

1
Należy pamiętać, że tworzysz nowy obiekt przy każdej iteracji zamiast aktualizować pojedynczy klon.
— mpen

1
@mpen dobre znalezisko. Dodałem wersję mutującą pojedynczy klon, ponieważ zasugerowałeś także rozprzestrzenianie argumentów zamiast przekazywania tablicy kluczy.
— Muhammet Enginar

7

Rozwiązanie TypeScript:

export function pick<T extends object, U extends keyof T>(obj: T, paths: Array<U>) {
    return paths.reduce((o, k) => {
        o[k] = obj[k];
        return o;
    }, Object.create(null));
}

Informacje o pisaniu pozwalają nawet na automatyczne uzupełnianie:

Problem zgłosili DefinitelyTyped dla U extends keyof Tsztuczki!


Nie działa dla mnie.
— Nuthinking

@Nuthinking Czy używasz VS Code?
— mpen

tak, używam VS Code.
— Nuthinking

@ Nuthinking I umieściłeś to w pliku .ts? To powinno działać. Właśnie spróbowałem ponownie
— MPpl


4

Dynamiczne rozwiązanie

['color', 'height'].reduce((a,b) => (a[b]=elmo[b],a), {})


3

Po prostu inny sposób ...

var elmo = { 
  color: 'red',
  annoying: true,
  height: 'unknown',
  meta: { one: '1', two: '2'}
}

var subset = [elmo].map(x => ({
  color: x.color,
  height: x.height
}))[0]

Możesz użyć tej funkcji z tablicą Objects =)


2

Co powiesz na:

function sliceObj(obj) {
  var o = {}
    , keys = [].slice.call(arguments, 1);
  for (var i=0; i<keys.length; i++) {
    if (keys[i] in obj) o[keys[i]] = obj[keys[i]];
  }
  return o;
}

var subset = sliceObj(elmo, 'color', 'height');

To się nie powiedzie, jeśli wartość właściwości to false(lub fałsz). jsfiddle.net/nfAs8
— Alxandr

Dlatego zmieniłem to na keys[i] in obj.
— elclanrs

2

Działa to dla mnie w konsoli Chrome. Masz z tym jakiś problem?

var { color, height } = elmo
var subelmo = { color, height }
console.log(subelmo) // {color: "red", height: "unknown"}

4
Czyta się to ładnie, ale tworzy dwie niepotrzebne zmienne, kolor i wysokość.
— user424174

Nie rozumiem twojego komentarza. Wymaganiem OP było stworzenie obiektu zawierającego te dwa elementy
— MSi

@MSi To nie tylko tworzy jeden obiekt, ale także tworzy dwie zmienne.
— Projekt Adrian

1

Przydział destrukcyjny z właściwościami dynamicznymi

To rozwiązanie dotyczy nie tylko konkretnego przykładu, ale ma bardziej ogólne zastosowanie:

const subset2 = (x, y) => ({[x]:a, [y]:b}) => ({[x]:a, [y]:b});

const subset3 = (x, y, z) => ({[x]:a, [y]:b, [z]:c}) => ({[x]:a, [y]:b, [z]:c});

// const subset4...etc.


const o = {a:1, b:2, c:3, d:4, e:5};


const pickBD = subset2("b", "d");
const pickACE = subset3("a", "c", "e");


console.log(
  pickBD(o), // {b:2, d:4}
  pickACE(o) // {a:1, c:3, e:5}
);

Możesz łatwo zdefiniować subset4itp., Aby uwzględnić więcej właściwości.


1

Dobry stary Array.prototype.reduce:

const selectable = {a: null, b: null};
const v = {a: true, b: 'yes', c: 4};

const r = Object.keys(selectable).reduce((a, b) => {
  return (a[b] = v[b]), a;
}, {});

console.log(r);

w tej odpowiedzi użyto magicznego przecinka, również: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator

jeśli chcesz się naprawdę zachwycić, jest to bardziej kompaktowe:

const r = Object.keys(selectable).reduce((a, b) => (a[b] = v[b], a), {});

Łącząc to wszystko w funkcję wielokrotnego użytku:

const getSelectable = function (selectable, original) {
  return Object.keys(selectable).reduce((a, b) => (a[b] = original[b], a), {})
};

const r = getSelectable(selectable, v);
console.log(r);

1
  1. konwertuj argumenty na tablicę

  2. użyj, Array.forEach()aby wybrać właściwość

    Object.prototype.pick = function(...args) {
       var obj = {};
       args.forEach(k => obj[k] = this[k])
       return obj
    }
    var a = {0:"a",1:"b",2:"c"}
    var b = a.pick('1','2')  //output will be {1: "b", 2: "c"}

4
Rozszerzenie prototypu typów rodzimych jest uważane za złą praktykę, choć mogłoby się to udać. Nie rób tego, jeśli piszesz bibliotekę.
— Emile Bergeron,

0
function splice()
{
    var ret = new Object();

    for(i = 1; i < arguments.length; i++)
        ret[arguments[i]] = arguments[0][arguments[i]];

    return ret;
}

var answer = splice(elmo, "color", "height");

0

Próbować

const elmo={color:"red",annoying:!0,height:"unknown",meta:{one:"1",two:"2"}};

const {color, height} = elmo; newObject = ({color, height});

console.log(newObject); //{ color: 'red', height: 'unknown' }

0

Dodając moje 2 centy do odpowiedzi Iwana Nosowa :

W moim przypadku potrzebowałem wielu kluczy do „wycięcia” z obiektu, więc staje się brzydki bardzo szybko i niezbyt dynamicznym rozwiązaniem:

const object = { a: 5, b: 6, c: 7, d: 8, aa: 5, bb: 6, cc: 7, dd: 8, aaa: 5, bbb: 6, ccc: 7, ddd: 8, ab: 5, bc: 6, cd: 7, de: 8  };
const picked = (({ a, aa, aaa, ab, c, cc, ccc, cd }) => ({ a, aa, aaa, ab, c, cc, ccc, cd }))(object);

console.log(picked);

Oto dynamiczne rozwiązanie wykorzystujące eval:

const slice = (k, o) => eval(`(${k} => ${k})(o)`);


const object    = { a: 5, b: 6, c: 7, d: 8, aa: 5, bb: 6, cc: 7, dd: 8, aaa: 5, bbb: 6, ccc: 7, ddd: 8, ab: 5, bc: 6, cd: 7, de: 8  };
const sliceKeys = '({ a, aa, aaa, ab, c, cc, ccc, cd })';

console.log( slice(sliceKeys, object) );

-2

Uwaga: chociaż pierwotne pytanie dotyczyło javascript, można to zrobić jQuery za pomocą poniższego rozwiązania

możesz rozszerzyć jquery, jeśli chcesz tutaj, przykładowy kod dla jednego wycinka:

jQuery.extend({
  sliceMe: function(obj, str) {
      var returnJsonObj = null;
    $.each( obj, function(name, value){
        alert("name: "+name+", value: "+value);
        if(name==str){
            returnJsonObj = JSON.stringify("{"+name+":"+value+"}");
        }

    });
      return returnJsonObj;
  }
});

var elmo = { 
  color: 'red',
  annoying: true,
  height: 'unknown',
  meta: { one: '1', two: '2'}
};


var temp = $.sliceMe(elmo,"color");
alert(JSON.stringify(temp));

oto skrzypce dla tego samego: http://jsfiddle.net/w633z/


16
Co to jest jquery?
— Christian Schlensker

1
@ChristianSchlensker It's javascript
— Kevin B
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.