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ąć?

Christian Schlensker
źródło
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)

Ivan Nosov
źródło
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

Ygg
źródło
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'};
Lauren
źródło
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' },
// ]
Josh z Qaribou
źródło
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 }
Estus Flask
źródło
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().

alex
źródło
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:

Code Maniac
źródło
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!

Wynicować
źródło
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'); });
Arthur Alvim
źródło
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)

Muhammet Enginar
źródło
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!

mpen
źródło
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
5

Użyj pickmetody biblioteki lodash, jeśli już z niej korzystasz.

var obj = { 'a': 1, 'b': '2', 'c': 3 };

_.pick(object, ['a', 'c']);

// => { 'a': 1, 'c': 3 }

https://lodash.com/docs/4.17.10#pick

Kashif Nazar
źródło
4

Dynamiczne rozwiązanie

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

Kamil Kiełczewski
źródło
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 =)

Arthur Araújo
źródło
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');
elclanrs
źródło
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"}
MSi
źródło
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.


źródło
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);
Alexander Mills
źródło
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"}
olivia
źródło
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");
Jan
źródło
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' }
mohan kumar
źródło
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) );
Igor
źródło
-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/

ManMohan Vyas
źródło
16
Co to jest jquery?
Christian Schlensker
1
@ChristianSchlensker It's javascript
Kevin B