假设我有一个对象:

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

我想用它的属性子集创建一个新对象。

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

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

我怎样才能做到呢?


当前回答

就像这个线程上的几个人一样,我同意evert的观点,最明显的老派方法实际上是最好的,但是为了好玩,让我提供另一种不可取的方法来做它在某些情况下,比如当你已经定义了你的子集,你想从另一个对象复制属性到它,其中包含一个超集或交叉集的属性。

设set = {a: 1, b: 2, c: 3}; 让子集= {a: null, b: null}; 尝试{ Object.assign (Object.seal(子集),集); } catch (e) { console.log('我想这样做<(^.^)^'); } console.log(子集);

其他回答

两种常见的方法是解构和传统的类似lodash的选择/省略实现。它们之间的主要实际区别是,解构需要一个键列表是静态的,不能省略它们,包括不存在的选择键,即它是包含的。这可能是可取的,也可能是不可取的,并且不能为析构语法而更改。

考虑到:

var obj = { 'foo-bar': 1, bar: 2, qux: 3 };

定期选择foo-bar, bar, baz键的预期结果:

{ 'foo-bar': 1, bar: 2 }

包容性挑选的预期结果:

{ 'foo-bar': 1, bar: 2, baz: undefined }

解构

析构语法允许用函数参数或变量对对象进行解构和重组。

限制在于键的列表是预定义的,它们不能像问题中描述的那样被列为字符串。如果键是非字母数字,例如foo-bar,则析构将变得更加复杂。

优点是它的性能解决方案对ES6来说是很自然的。

缺点是键的列表是重复的,在列表很长的情况下,这会导致冗长的代码。由于在这种情况下解构会重复对象文字语法,因此可以原样复制和粘贴列表。

IIFE

const subset = (({ 'foo-bar': foo, bar, baz }) => ({ 'foo-bar': foo, bar, baz }))(obj);

临时变量

const { 'foo-bar': foo, bar, baz } = obj;
const subset = { 'foo-bar': foo, bar, baz };

字符串列表

任意选择的键列表由字符串组成,如问题所要求的。这允许不预定义它们,并使用包含键名的变量,['foo-bar', someKey,…moreKeys]。

ECMAScript 2017有Object。entry和Array.prototype。包括,ECMAScript 2019有object . fromentry,它们可以在需要时填充。

一行程序

考虑到要选择的对象包含额外的键,通常从列表中迭代键比从对象键更有效,如果需要省略键,反之亦然。

Pick (ES5)

var subset = ['foo-bar', 'bar', 'baz']
.reduce(function (obj2, key) {
  if (key in obj) // line can be removed to make it inclusive
    obj2[key] = obj[key];
  return obj2;
}, {});

自己的 (ES5)

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

拾取 (ES6)

const subset = ['foo-bar', 'bar', 'baz']
.filter(key => key in obj) // line can be removed to make it inclusive
.reduce((obj2, key) => (obj2[key] = obj[key], obj2), {});

省略 (ES6)

const subset = Object.keys(obj)
.filter(key => ['baz', 'qux'].indexOf(key) < 0)
.reduce((obj2, key) => (obj2[key] = obj[key], obj2), {});

挑选 (ES2019)

const subset = Object.fromEntries(
  ['foo-bar', 'bar', 'baz']
  .filter(key => key in obj) // line can be removed to make it inclusive
  .map(key => [key, obj[key]])
);

省略 (ES2019)

const subset = Object.fromEntries(
  Object.entries(obj)
  .filter(([key]) => !['baz', 'qux'].includes(key))
);

可重用的功能

一行程序可以表示为类似于Lodash pick或省略的可重用帮助函数,其中通过参数pick(obj, 'foo-bar', 'bar', 'baz')传递键列表。

const pick = (obj, ...keys) => Object.fromEntries(
  keys
  .filter(key => key in obj)
  .map(key => [key, obj[key]])
);

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

const omit = (obj, ...keys) => Object.fromEntries(
  Object.entries(obj)
  .filter(([key]) => !keys.includes(key))
);

你也可以使用Lodash。

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

作为补充,假设你有一个“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'}
    }
];

如果你想要同样的行为,使用lodash,你只需要:

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

只是另一种方式……

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]

你可以在Objects =)数组中使用这个函数

值得注意的是,Zod模式在默认情况下会删除未知属性。如果您已经在使用Zod,那么它很可能适合您的开发过程。

https://github.com/colinhacks/zod

import { z } from "zod";

// muppet schema
const muppet = z.object({
  color: z.string(),
  annoying: z.boolean(),
  height: z.string(),
  meta: z.object({ one: z.string(), two: z.string() }),
});

// TypeScript type if you want it
type TMuppet = z.infer<typeof muppet>;

// elmo example
const elmo: TMuppet = {
  color: "red",
  annoying: true,
  height: "unknown",
  meta: { one: "1", two: "2" },
};

// get a subset of the schema (another schema) if you want
const subset = muppet.pick({ color: true, height: true });

// parsing removes unknown properties by default
subset.parse(elmo); // { color: 'red', height: 'unknown' }

我添加这个答案,因为没有一个答案使用逗号操作符。

解构赋值和运算符很简单

Const对象= {a: 5, b: 6, c: 7}; Const selected = ({a,c} = object, {a,c}) console.log(选择);