it-swarm.dev

كيفية الحصول على مجموعة فرعية من خصائص كائن جافا سكريبت

قل لدي كائن:

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

أريد إنشاء كائن جديد بمجموعة فرعية من خصائصه.

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

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

كيف يمكنني تحقيق هذا؟

268
Christian Schlensker

باستخدام تدمير الكائنات واختزال الممتلكات

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

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

من فيليب كويتش:

هذه هي في الحقيقة مجرد وظيفة مجهولة الهوية يتم استدعاؤها على الفور. كل هذا يمكن العثور عليه على Destructuring Assignment page على MDN. هنا شكل موسع

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)
442
Ivan Nosov

أقترح إلقاء نظرة على Lodash ؛ انها لديها الكثير من وظائف فائدة كبيرة.

على سبيل المثال pick() سيكون بالضبط ما تبحث عنه:

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

كمان

102
Ygg

إذا كنت تستخدم ES6 ، فهناك طريقة موجزة للغاية للقيام بذلك باستخدام التدمير. يتيح لك التدمير إمكانية إضافة كائنات بسهولة باستخدام حيز ، لكنه يسمح لك أيضًا بإنشاء كائنات فرعية بالطريقة نفسها.

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'};
68
Lauren

على الرغم من أنها أكثر نشاطًا قليلاً ، إلا أنه يمكنك تحقيق ما أوصى به أي شخص آخر بتسطير أسفل السطر/lodash قبل عامين ، باستخدام Array.prototype.reduce .

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

تعمل هذه الطريقة على حلها من الجانب الآخر: بدلاً من أخذ كائن وتمرير أسماء الخصائص إليه لاستخراجها ، أخذ مجموعة من أسماء الخصائص وتقليلها إلى كائن جديد.

على الرغم من أن الأمر أكثر تشعبًا في أبسط الحالات ، إلا أن عملية معاودة الاتصال هنا مفيدة جدًا ، حيث يمكنك بسهولة تلبية بعض المتطلبات الشائعة ، على سبيل المثال تغيير خاصية "اللون" إلى "لون" على الكائن الجديد ، صفائف مسطحة ، وما إلى ذلك - أي من الأشياء التي تحتاج إلى القيام بها عند تلقي كائن من خدمة/مكتبة واحدة وبناء كائن جديد مطلوب في مكان آخر. في حين أن تسطير/تسطير الأحرف الممتازة/libs ممتاز ، يتم تنفيذه جيدًا ، هذا هو الأسلوب المفضل لدي لأقل اعتمادًا على البائع ، وأسلوب أكثر بساطة وأكثر اتساقًا عندما يصبح منطق بناء المجموعات الفرعية أكثر تعقيدًا.

تحرير: es7 نسخة من نفسه:

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

تحرير: مثال لطيف للكاري ، أيضا! لديك وظيفة "اختيار" لإرجاع وظيفة أخرى.

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

ما ورد أعلاه قريب جدًا من الطريقة الأخرى ، إلا أنه يتيح لك بناء "منتقي" سريعًا. مثلا.

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

ما يميز هذه الطريقة بشكل خاص ، هو أنه يمكنك بسهولة نقل "اللقطات" المختارة إلى أي شيء يأخذ وظيفة ، على سبيل المثال Array#map:

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

لا يوجد شيء مثل هذا مدمج في المكتبة الأساسية ، ولكن يمكنك استخدام تدمير الكائنات للقيام بذلك ...

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

يمكنك أيضا كتابة وظيفة فائدة تفعل ذلك ...

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

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

المكتبات مثل Lodash لها أيضًا _.pick().

25
alex

أقوم بإضافة هذه الإجابة لأن أيا من الإجابة المستخدمة Comma operator .

من السهل جدًا استخدام تعيين التدمير و , المشغل

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

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

حل واحد آخر:

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

هذا يبدو أكثر قابلية للقراءة بالنسبة لي من أي إجابة إلى حد كبير حتى الآن ، ولكن ربما هذا فقط أنا!

9
Evert

يمكنك استخدام Lodash أيضا.

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

تكملة ، دعنا نقول أن لديك مجموعة من "إلمو":

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'}
    }
];

إذا كنت تريد نفس السلوك ، باستخدام lodash ، فإنك فقط:

var subsets = _.map(elmos, function(Elm) { return _.pick(Elm, 'color', 'height'); });
9
Arthur Alvim

من المستحيل الوصول إلى المتغيرات المسماة ديناميكيًا في JavaScript كما هو موضح في هذا السؤال .

إلى ضبط المفاتيح بشكل حيوي ، يمكنك استخدام وظيفة الاختزال دون تغيير الكائن كما يلي:

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

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

console.log(getSubset(['color', 'annoying'], elmo));
7
Muhammet Enginar

استخدم طريقة pick من مكتبة lodash إذا كنت تستخدم بالفعل.

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

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

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

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

4
Kashif Nazar

مجرد طريقة أخرى ...

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]

يمكنك استخدام هذه الوظيفة مع مجموعة من الكائنات =)

4
Arthur Araújo

هذا يعمل لي في وحدة التحكم كروم. أي مشكلة مع هذا؟

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

كيف حول:

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');
1
elclanrs

تدمير المهمة مع الخصائص الديناميكية

لا ينطبق هذا الحل على المثال المحدد فحسب ، بل ينطبق بشكل عام:

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}
);

يمكنك بسهولة تحديد subset4 وما إلى ذلك لتأخذ المزيد من الخصائص في الاعتبار.

1
user6445533
  1. تحويل الحجج إلى مجموعة

  2. استخدم Array.forEach() لاختيار العقار

    Object.prototype.pick = function() {
       var obj = {};
       var args = arguments
       Array.from(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"}
    
1
olivia

محاولة

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
mohan kumar

حل 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));
}

تتيح معلومات الكتابة حتى الإكمال التلقائي:

الرصيد إلى definitelyTyped ل U extends keyof T خدعة!

0
mpen
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
John

هنا حل كامل لـ Node.js

>>> npm i --save lodash.pick
var pick = require('lodash.pick');

var user = {name: 'Bill', number:'1', age:'10'}
var subset =  pick(user, ['name', 'number']);
0
Thomas G.

محاولة

['color', 'height'].reduce((a,b) => (a[b]=elmo[b],a), {})
let elmo = { 
  color: 'red',
  annoying: true,
  height: 'unknown',
  meta: { one: '1', two: '2'}
};

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

console.log( subset );
0
Kamil Kiełczewski

حسن 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);

تستخدم هذه الإجابة المشغل الفاصل السحري ، أيضًا: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator

إذا كنت ترغب في أن تكون خياليًا ، فهذا أكثر إحكاما:

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

وضعه معًا في وظيفة قابلة لإعادة الاستخدام:

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);
0
Alexander Mills