ES6中按键过滤对象属性

497

假设我有一个对象:

{
  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的扩展运算符来实现一个简洁的方法。


ES6没有对象展开运算符,而且在这里你也不需要它们。 - Bergi
1
可能是JavaScript:filter()用于对象的重复问题。 - Jonathan H
@DanDascalescu 但是这个答案提供了一种ES6的方法来完成OP所要求的,不是吗? - Jonathan H
2
如果我想按键/值进行过滤怎么办? - jmchauv
31个回答

2
许多上述解决方案会针对raw中的每个键重复调用Array.prototype.includes,这将使解决方案的时间复杂度为O(n·m)(其中n是对象中键的数量,m是允许列表的长度)。
可以通过使用允许集合来避免这种情况,但是遍历allowed键并将它们复制到一个最初为空的对象中会得到非常简单、易读的代码,并且时间复杂度为O(m)。

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

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

const filtered = {};
for (const key of allowed) {
  if (key in raw) filtered[key] = raw[key];
}

console.log(filtered);

如果你想避免复制继承属性,你也可以使用raw.hasOwnProperty(key)而不是key in raw


2

另一种简便方法

function filterByKey(v,keys){
  const newObj ={};
  keys.forEach(key=>{v[key]?newObj[key]=v[key]:''});
  return newObj;
}

//given
let obj ={ foo: "bar", baz: 42,baz2:"blabla" , "spider":"man", monkey:true};

//when
let outObj =filterByKey(obj,["bar","baz2","monkey"]);

//then 
console.log(outObj);
  //{
  //  "baz2": "blabla",
  //  "monkey": true
  //}


2
您可以从对象中删除特定属性。最初的回答中提到了这一点。
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;

1
好的,这个怎么样:

OK, 这个怎么样:

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

并且像这样调用它:
filteredObject(myData, ['item2']); //{item1: { key: 'sdfd', value:'sdfd' }, item3: { key: 'sdfd', value:'sdfd' }}

1
这个函数将根据一组键过滤对象,与之前的答案相比更有效,因为它不必在调用reduce之前使用Array.filter。因此,它是O(n),而不是O(n + filtered)。
function filterObjectByKeys (object, keys) {
  return Object.keys(object).reduce((accum, key) => {
    if (keys.includes(key)) {
      return { ...accum, [key]: object[key] }
    } else {
      return accum
    }
  }, {})
}

1

我很惊讶还没有人建议过这个。它非常清晰明了,可以明确哪些键需要保留。

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

该方法将添加一个原始数组中不存在的键。这可能是一个问题,至少应该指出来。 - ponchietto
1
我认为这个人已经建议过了:https://dev59.com/21kT5IYBdhLWcg3wV-CY#49340650 - charles-allen
1
“我很惊讶为什么还没有人建议这个。” 实际上,这个建议已经在2018年11月由Novy和2019年12月由ghanshyam bendkoli提出了。 - VLAZ

0

使用PropPick


pick('item1 item3', obj);
// {
//   item1: { key: 'sdfd', value:'sdfd' },
//   item3: { key: 'sdfd', value:'sdfd' }
// }


0
另一种方法是使用Array.prototype.forEach()

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

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

var finalObj = {};
allowed.forEach(allowedVal => {
  if (raw[allowedVal])
    finalObj[allowedVal] = raw[allowedVal]
})
console.log(finalObj)

它包括仅在原始数据中可用的键的值,从而防止添加任何垃圾数据。


0
在循环过程中,当遇到特定的属性/键时不返回任何内容,并继续处理其余部分:
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>
    );
});

0

这将是我的解决方案:

const filterObject = (obj, condition) => {
    const filteredObj = {};
    Object.keys(obj).map(key => {
      if (condition(key)) {
        dataFiltered[key] = obj[key];
      }
    });
  return filteredObj;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接