Javascript 在ES6中按键筛选对象属性

Javascript 在ES6中按键筛选对象属性,javascript,ecmascript-6,filter,Javascript,Ecmascript 6,Filter,假设我有一个对象: { item1: { key: 'sdfd', value:'sdfd' }, item2: { key: 'sdfd', value:'sdfd' }, item3: { key: 'sdfd', value:'sdfd' } } 我想通过过滤上面的对象来创建另一个对象,这样我就有了类似的东西 { item1: { key: 'sdfd', value:'sdfd' }, item3: { key: 'sdfd', value:'sdfd'

假设我有一个对象:

{
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
}
我想通过过滤上面的对象来创建另一个对象,这样我就有了类似的东西

 {
    item1: { key: 'sdfd', value:'sdfd' },
    item3: { key: 'sdfd', value:'sdfd' }
 }

我正在寻找一种干净的方法来使用Es6实现这一点,因此我可以使用排列运算符。

如果您有一个允许值的列表,您可以使用以下方法轻松地将它们保留在对象中:

const-raw={
项1:{键:'sdfd',值:'sdfd'},
项2:{键:'sdfd',值:'sdfd'},
项3:{键:'sdfd',值:'sdfd'}
};
允许的常量=['item1','item3'];
const filtered=Object.keys(原始)
.filter(键=>允许。包括(键))
.reduce((对象,键)=>{
obj[key]=原始[key];
返回obj;
}, {});

console.log(过滤)
您可以添加一个过滤器的通用
(使用generic
或reduce
实现),这样您就可以像过滤数组一样轻松地过滤对象——

const oreduce = (f, acc, o) =>
  Object
    .entries (o)
    .reduce
      ( (acc, [ k, v ]) => f (acc, v, k, o)
      , acc
      )

const ofilter = (f, o) =>
  oreduce
    ( (acc, v, k, o)=>
        f (v, k, o)
          ? Object.assign (acc, {[k]: v})
          : acc
    , {}
    , o
    )
我们可以看到它在这里工作-

const data =
  { item1: { key: 'a', value: 1 }
  , item2: { key: 'b', value: 2 }
  , item3: { key: 'c', value: 3 }
  }

console.log
  ( ofilter
      ( (v, k) => k !== 'item2'
      , data
      )
      // [ { item1: { key: 'a', value: 1 } }
      // , { item3: { key: 'c', value: 3 } }
      // ]

  , ofilter
      ( x => x.value === 3
      , data
      )
      // [ { item3: { key: 'c', value: 3 } } ]
  )
在下面自己的浏览器中验证结果-

const-oreduce=(f,acc,o)=>
对象
.条目(o)
减少
((acc,[k,v])=>f(acc,v,k,o)
,acc
)
滤波器常数=(f,o)=>
减少
((acc、v、k、o)=>
f(v,k,o)
?Object.assign(acc,{[k]:v})
:acc
, {}
,o
)
常量数据=
{item1:{key:'a',value:1}
,item2:{key:'b',value:2}
,item3:{key:'c',value:3}
}
console.log
(过滤器的)
((v,k)=>k!=='item2'
,数据
)
//[{item1:{key:'a',value:1}
//,{item3:{key:'c',value:3}
// ]
,of filter
(x=>x.value==3
,数据
)
//[{item3:{key:'c',value:3}]

)
如果您不介意使用ES6语法,我发现最干净的方法是:

现在,
newData
包含:

{
  item1: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};
或者,如果密钥存储为字符串:

const key = 'item2';
const { [key]: _, ...newData } = data;

在后一种情况下,
[key]
转换为
item2
,但由于您使用的是
const
赋值,因此需要为赋值指定名称<代码>.
表示丢弃值

更一般地说:

const { item2, ...newData } = data; // Assign item2 to item2
const { item2: someVarName, ...newData } = data; // Assign item2 to someVarName
const { item2: _, ...newData } = data; // Assign item2 to _
const { ['item2']: _, ...newData } = data; // Convert string to key first, ...
这不仅可以将您的操作简化为一行,而且不需要您知道其他键(您希望保留的键)是什么

一个简单的实用程序函数如下所示:

function removePropFromObject(obj, prop) {
  const { [prop]: _, ...rest } = obj
  return { ...rest }
}
filteredObject(myData, ['item2']); //{item1: { key: 'sdfd', value:'sdfd' }, item3: { key: 'sdfd', value:'sdfd' }}
const base = {
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};

const filtered = (
    source => { 
        with(source){ 
            return {item1, item3} 
        } 
    }
)(base);

// one line
const filtered = (source => { with(source){ return {item1, item3} } })(base);

我最近就是这样做的:

const dummyObj = Object.assign({}, obj);
delete dummyObj[key];
const target = Object.assign({}, {...dummyObj});

你能找到的最干净的方法就是


没有什么是以前没有说过的,但要将一些答案与ES6的一般答案结合起来:

const-raw={
项1:{键:'sdfd',值:'sdfd'},
项2:{键:'sdfd',值:'sdfd'},
项3:{键:'sdfd',值:'sdfd'}
};
常量filteredKeys=['item1','item3'];
const filteredKeys=filteredKeys
.reduce((obj,key)=>({…obj[key]:raw[key]}),{});
console.log(过滤)背驮在上面

这是一个可重用的版本

Object.filterByKey = function (obj, predicate) {
  return Object.keys(obj)
    .filter(key => predicate(key))
    .reduce((out, key) => {
      out[key] = obj[key];
      return out;
    }, {});
}
称之为使用

const raw = {
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};

const allowed = ['item1', 'item3'];

var filtered = Object.filterByKey(raw, key => 
  return allowed.includes(key));
});

console.log(filtered);

ES6 arrow函数的美妙之处在于,您不必将
allowed
作为参数传入。

好的,这样如何:

const myData = {
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};

function filteredObject(obj, filter) {
  if(!Array.isArray(filter)) {
   filter = [filter.toString()];
  }
  const newObj = {};
  for(i in obj) {
    if(!filter.includes(i)) {
      newObj[i] = obj[i];
    }
  }
  return newObj;
}
这样称呼它:

function removePropFromObject(obj, prop) {
  const { [prop]: _, ...rest } = obj
  return { ...rest }
}
filteredObject(myData, ['item2']); //{item1: { key: 'sdfd', value:'sdfd' }, item3: { key: 'sdfd', value:'sdfd' }}
const base = {
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};

const filtered = (
    source => { 
        with(source){ 
            return {item1, item3} 
        } 
    }
)(base);

// one line
const filtered = (source => { with(source){ return {item1, item3} } })(base);

这只是现代JS的一行中的另一个解决方案,没有外部库

我在玩“解构”功能:

const-raw={
项1:{键:'sdfd',值:'sdfd'},
项2:{键:'sdfd',值:'sdfd'},
项3:{键:'sdfd',值:'sdfd'}
};
var myNewRaw=({item1,item3})=>({item1,item3}))(raw);

console.log(myNewRaw)实现这一点的方法有很多。使用关键帧过滤器减少方法,这不是最有效的方法

相反,使用
for…in
循环遍历对象的键,或循环遍历允许的键,然后组合新对象的性能提高约50%



a。有关简单用例的基准,请参见。结果会因浏览器而异。

这里的答案肯定是合适的,但速度有点慢,因为它们需要在对象中每个属性的白名单中循环。对于大型数据集,下面的解决方案要快得多,因为它只在白名单中循环一次:

const数据={
允许1:‘废话’,
允许2:‘废话’,
不允许:“哇,
超级敏感信息:“哇,
允许3:‘呜呜’
};
常量白名单=['allowed1','allowed2','allowed3'];
函数清理(数据、白名单){
返回白名单.reduce(
(结果,键)=>
数据[键]!==未定义
?Object.assign(结果,{[key]:数据[key]})
:结果,
{}
);
}
const result=sanitize(数据,白名单);

控制台日志(结果)您可以执行以下操作:

function removePropFromObject(obj, prop) {
  const { [prop]: _, ...rest } = obj
  return { ...rest }
}
filteredObject(myData, ['item2']); //{item1: { key: 'sdfd', value:'sdfd' }, item3: { key: 'sdfd', value:'sdfd' }}
const base = {
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};

const filtered = (
    source => { 
        with(source){ 
            return {item1, item3} 
        } 
    }
)(base);

// one line
const filtered = (source => { with(source){ return {item1, item3} } })(base);

这是可行的,但不是很清楚,另外不建议使用
with
语句()。

不使用
过滤器的简单解决方案可以通过
对象.entries()
而不是
对象.keys()


此函数将根据键列表筛选对象,它比前面的答案更有效,因为它在调用reduce之前不必使用Array.filter。所以它的O(n)与O(n+过滤)


好的,这个班轮怎么样

    const raw = {
      item1: { key: 'sdfd', value: 'sdfd' },
      item2: { key: 'sdfd', value: 'sdfd' },
      item3: { key: 'sdfd', value: 'sdfd' }
    };

    const filteredKeys = ['item1', 'item3'];

    const filtered = Object.assign({}, ...filteredKeys.map(key=> ({[key]:raw[key]})));

在循环过程中,遇到某些属性/键时不返回任何内容,并继续执行其余操作:

const loop = product =>
Object.keys(product).map(key => {
    if (key === "_id" || key === "__v") {
        return; 
    }
    return (
        <ul className="list-group">
            <li>
                {product[key]}
                <span>
                    {key}
                </span>
            </li>
        </ul>
    );
});
const循环=产品=>
Object.keys(product.map)(key=>{
如果(键==“|id”|键==“|v”){
返回;
}
返回(
  • {产品[密钥]} {key}
); });
现在,您可以使用对象将其缩短并简化。fromEntries方法(检查浏览器支持):


阅读更多信息:

您可以删除对象上的特殊属性

items={
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
}

// Example 1
var key = "item2";
delete items[key]; 

// Example 2
delete items["item2"];

// Example 3
delete items.item2;

简单的方法!这样做。

const myData={
项1:{键:'sdfd',值:'sdfd'
const filteredObject = Object.fromEntries(Object.entries(originalObject).filter(([key, value]) => key !== uuid))
const unfilteredObj = {a: ..., b:..., c:..., x:..., y:...}

const filterObject = ({a,b,c}) => ({a,b,c})
const filteredObject = filterObject(unfilteredObject)
const unfilteredObj = {a: ..., b:..., c:..., x:..., y:...}

const filteredObject = (({a,b,c})=>({a,b,c}))(unfilteredObject);
const raw = {
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};

const allowed = ['item1', 'item3'];

const filtered = allowed.reduce((obj, key) => { 
  obj[key] = raw[key]; 
  return obj 
}, {})

console.log(filtered);
const object = Object.fromEntries(
  Object.entries(raw).filter(([key, value]) => allowed.includes(key))
);
const filterObject = (obj, condition) => {
    const filteredObj = {};
    Object.keys(obj).map(key => {
      if (condition(key)) {
        dataFiltered[key] = obj[key];
      }
    });
  return filteredObj;
}
JSON.parse(JSON.stringify(raw, ['key', 'value', 'item1', 'item3']))