在不改变原始对象的情况下,从特定键的对象中删除值的好方法和简短方法是什么?
我想做类似的事情:
let o = {firstname: 'Jane', lastname: 'Doe'};
let o2 = doSomething(o, 'lastname');
console.log(o.lastname); // 'Doe'
console.log(o2.lastname); // undefined
我知道这些任务有很多不变的库,但我想在没有库的情况下离开。但要做到这一点,一个要求是在整个代码中使用一种简单易用的方法,而不是将方法作为效用函数抽象出来。
E.g。要添加值,我会执行以下操作:
let o2 = {...o1, age: 31};
这很简短,易记,也不需要实用功能。
是否有类似的东西用于删除值? ES6非常受欢迎。
非常感谢!
答案 0 :(得分:160)
您可以使用棘手的Destructuring assignment:
从对象中删除属性const doSomething = (obj, prop) => {
let {[prop]: omit, ...res} = obj
return res
}
但是,如果要删除的属性名称是静态的,那么您可以使用简单的单行删除它:
let {lastname, ...o2} = o
最简单的方法就是或者你可以在变异之前克隆你的对象:
const doSomething = (obj, prop) => {
let res = Object.assign({}, obj)
delete res[prop]
return res
}
或者您可以使用omit
function from lodash
utility library:
let o2 = _.omit(o, 'lastname')
它可以作为lodash包的一部分提供,也可以作为独立的lodash.omit包提供。
答案 1 :(得分:13)
一线解决方案
public class NotifierEntity
{
ICollection<SqlParameter> sqlParameters = new List<SqlParameter>();
public String SqlQuery { get; set; }
public String SqlConnectionString { get; set; }
public ICollection<SqlParameter> SqlParameters
{
get
{
return sqlParameters;
}
set
{
sqlParameters = value;
}
}
public static NotifierEntity FromJson(String value)
{
if (String.IsNullOrEmpty(value))
throw new ArgumentNullException("NotifierEntity Value can not be null!");
return new JavaScriptSerializer().Deserialize<NotifierEntity>(value);
}
}
public static class NotifierEntityExtentions
{
public static String ToJson(this NotifierEntity entity)
{
if (entity == null)
throw new ArgumentNullException("NotifierEntity can not be null!");
return new JavaScriptSerializer().Serialize(entity);
}
}
public class PushSqlDependency
{
static PushSqlDependency instance = null;
readonly SqlDependencyRegister sqlDependencyNotifier;
readonly Action<String> dispatcher;
public static PushSqlDependency Instance(NotifierEntity notifierEntity, Action<String> dispatcher)
{
if (instance == null)
instance = new PushSqlDependency(notifierEntity, dispatcher);
return instance;
}
private PushSqlDependency(NotifierEntity notifierEntity, Action<String> dispatcher)
{
this.dispatcher = dispatcher;
sqlDependencyNotifier = new SqlDependencyRegister(notifierEntity);
sqlDependencyNotifier.SqlNotification += OnSqlNotification;
}
internal void OnSqlNotification(object sender, SqlNotificationEventArgs e)
{
dispatcher("Refresh123");
}
}
public class SqlDependencyRegister
{
public event SqlNotificationEventHandler SqlNotification;
readonly NotifierEntity notificationEntity;
internal SqlDependencyRegister(NotifierEntity notificationEntity)
{
this.notificationEntity = notificationEntity;
RegisterForNotifications();
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security",
"CA2100:Review SQL queries for security vulnerabilities")]
void RegisterForNotifications()
{
using (var sqlConnection = new SqlConnection(notificationEntity.SqlConnectionString))
using (var sqlCommand = new SqlCommand(notificationEntity.SqlQuery, sqlConnection))
{
foreach (var sqlParameter in notificationEntity.SqlParameters)
{
sqlCommand.Parameters.Add(sqlParameter);
}
sqlCommand.Notification = null;
var sqlDependency = new SqlDependency(sqlCommand);
sqlDependency.OnChange += OnSqlDependencyChange;
if (sqlConnection.State == ConnectionState.Closed)
sqlConnection.Open();
sqlCommand.ExecuteNonQuery();
}
}
void OnSqlDependencyChange(object sender, SqlNotificationEventArgs e)
{
if (SqlNotification != null)
SqlNotification(sender, e);
RegisterForNotifications();
}
}
public delegate void SqlNotificationEventHandler(object sender, SqlNotificationEventArgs e);
答案 2 :(得分:13)
使用ES7对象分解:
const myObject = {
a: 1,
b: 2,
c: 3
};
const { a, ...noA } = myObject;
console.log(noA); // => { b: 2, c: 3 }
答案 3 :(得分:3)
正如上面的评论中所建议的,如果您想扩展此项以从object
移除多个项目,我想使用filter
。和reduce
例如
const o = {
"firstname": "Jane",
"lastname": "Doe",
"middlename": "Kate",
"age": 23,
"_id": "599ad9f8ebe5183011f70835",
"index": 0,
"guid": "1dbb6a4e-f82d-4e32-bb4c-15ed783c70ca",
"isActive": true,
"balance": "$1,510.89",
"picture": "http://placehold.it/32x32",
"eyeColor": "green",
"registered": "2014-08-17T09:21:18 -10:00",
"tags": [
"consequat",
"ut",
"qui",
"nulla",
"do",
"sunt",
"anim"
]
};
const removeItems = ['balance', 'picture', 'tags']
console.log(formatObj(o, removeItems))
function formatObj(obj, removeItems) {
return {
...Object.keys(obj)
.filter(item => !isInArray(item, removeItems))
.reduce((newObj, item) => {
return {
...newObj, [item]: obj[item]
}
}, {})
}
}
function isInArray(value, array) {
return array.indexOf(value) > -1;
}
答案 4 :(得分:1)
添加一些香料以提高性能。检查此螺纹波纹管
https://github.com/googleapis/google-api-nodejs-client/issues/375
使用delete运算符会降低性能 V8隐藏类模式。一般建议不要使用 它。
或者,要删除对象自身的可枚举属性,我们可以 创建没有这些属性的新对象副本(例如,使用 lodash):
_。omit(o,'prop','prop2')
或者甚至将属性值定义为null或undefined(这是 序列化为JSON时被隐式忽略):
o.prop =未定义
您也可以使用破坏方式
const {remov1, remov2, ...new} = old;
old = new;
还有一个更实用的示例:
this._volumes[this._minCandle] = undefined;
{
const {[this._minCandle]: remove, ...rest} = this._volumes;
this._volumes = rest;
}
如您所见,可以将[somePropsVarForDynamicName]: scopeVarName
语法用于动态名称。并且您可以将所有内容放在方括号(新块)中,以便将其余部分收集在此之后。
exec:
或者我们可以使用类似的功能
function deleteProps(obj, props) {
if (!Array.isArray(props)) props = [props];
return Object.keys(obj).reduce((newObj, prop) => {
if (!props.includes(prop)) {
newObj[prop] = obj[prop];
}
return newObj;
}, {});
}
打字稿
function deleteProps(obj: Object, props: string[]) {
if (!Array.isArray(props)) props = [props];
return Object.keys(obj).reduce((newObj, prop) => {
if (!props.includes(prop)) {
newObj[prop] = obj[prop];
}
return newObj;
}, {});
}
用法:
let a = {propH: 'hi', propB: 'bye', propO: 'ok'};
a = deleteProps(a, 'propB');
// or
a = deleteProps(a, ['propB', 'propO']);
这样,可以创建一个新对象。并且保留对象的快速属性。哪个可能重要或重要。如果映射和对象将被多次访问。
关联undefined
也是一个不错的选择。当您负担得起时。对于键,您也可以检查该值。例如,要获取所有活动键,您可以执行以下操作:
const allActiveKeys = Object.keys(myObj).filter(k => myObj[k] !== undefined);
//or
const allActiveKeys = Object.keys(myObj).filter(k => myObj[k]); // if any false evaluated value is to be stripped.
未定义虽然不适用于大列表。否则随着时间的推移就会有很多道具加入其中。随着内存使用量的增长,而且永远不会清除。因此,这取决于用法。只是创建一个新对象似乎是个好方法。
然后Premature optimization is the root of all evil
就会出现。因此,您需要注意一些折衷。以及需要什么,不需要什么。
它已从版本5中删除。您在存储库中找不到它。这里是一个谈论它的问题。
https://github.com/lodash/lodash/issues/2930
答案 5 :(得分:1)
如果您尝试解构,我的问题是来自ESLint规则标准的可接受的答案
const { notNeeded, alsoNotNeeded, ...rest } = { ...ogObject };
这两个新变量notNeeded
和alsoNotNeeded
可能会因您的设置而引发警告或错误,因为它们现在未使用。那么,为什么要创建未使用的新变量呢?
我认为您需要真正使用delete
函数。
答案 6 :(得分:0)
具有lodash cloneDeep和删除
(注意:lodash克隆可代替浅对象使用)
const obj = {a: 1, b: 2, c: 3}
const unwantedKey = 'a'
const _ = require('lodash')
const objCopy = _.cloneDeep(obj)
delete objCopy[unwantedKey]
// objCopy = {b: 2, c: 3}
答案 7 :(得分:0)
对于我的代码,我想要map()的返回值的简短版本,但多行/多操作运算的解决方案却“丑陋”。关键功能是旧的void(0)
可以解析为undefined
。
let o2 = {...o, age: 31, lastname: void(0)};
该属性保留在对象中:
console.log(o2) // {firstname: "Jane", lastname: undefined, age: 31}
但是传输框架会帮我杀死它(b.c. stringify):
console.log(JSON.stringify(o2)) // {"firstname":"Jane","age":31}
答案 8 :(得分:0)
我为我写了关于问题的大函数。该函数将 props(不是它本身,只有值)、数组等的所有值清除为多维。
注意:函数清除数组中的元素,数组变为空数组。也许这种情况可以添加为可选功能。
https://gist.github.com/semihkeskindev/d979b169e4ee157503a76b06573ae868
function clearAllValues(data, byTypeOf = false) {
let clearValuesTypeOf = {
boolean: false,
number: 0,
string: '',
}
// clears array if data is array
if (Array.isArray(data)) {
data = [];
} else if (typeof data === 'object' && data !== null) {
// loops object if data is object
Object.keys(data).forEach((key, index) => {
// clears array if property value is array
if (Array.isArray(data[key])) {
data[key] = [];
} else if (typeof data[key] === 'object' && data !== null) {
data[key] = this.clearAllValues(data[key], byTypeOf);
} else {
// clears value by typeof value if second parameter is true
if (byTypeOf) {
data[key] = clearValuesTypeOf[typeof data[key]];
} else {
// value changes as null if second parameter is false
data[key] = null;
}
}
});
} else {
if (byTypeOf) {
data = clearValuesTypeOf[typeof data];
} else {
data = null;
}
}
return data;
}
这是一个没有删除道具清除所有值的示例
let object = {
name: 'Semih',
lastname: 'Keskin',
brothers: [
{
name: 'Melih Kayra',
age: 9,
}
],
sisters: [],
hobbies: {
cycling: true,
listeningMusic: true,
running: false,
}
}
console.log(object);
// output before changed: {"name":"Semih","lastname":"Keskin","brothers":[{"name":"Melih Kayra","age":9}],"sisters":[],"hobbies":{"cycling":true,"listeningMusic":true,"running":false}}
let clearObject = clearAllValues(object);
console.log(clearObject);
// output after changed: {"name":null,"lastname":null,"brothers":[],"sisters":[],"hobbies":{"cycling":null,"listeningMusic":null,"running":null}}
let clearObject2 = clearAllValues(object);
console.log(clearObject2);
// output after changed by typeof: {"name":"","lastname":"","brothers":[],"sisters":[],"hobbies":{"cycling":false,"listeningMusic":false,"running":false}}