【问题标题】:Javascript | Loop through array of objects using against an objectJavascript |使用对象循环遍历对象数组
【发布时间】:2019-12-16 16:40:10
【问题描述】:

我有一个对象数组如下:

const objArray = [
    {scope: "xx", sector: "yy", status: "pending", country: "USA"},
    {scope: "zz", sector: "yy", status: "pending", country: "USA"}
    {scope: "xx", sector: "yy", status: "pending", country: "USA"}
]

还有一个对象如下:

const compare = {scope: "xx", sector: "yy"}

或者那个:

const compare = {scope: "xx"}

或者那个:

const compare = {scope: "yy"}

我想使用这三个 compare 对象之一遍历对象数组,并返回与这三个 compare 示例对象中的任何一个匹配的所有对象,这些对象具有相同的 scopesector 或 @仅限 987654329@ 或仅限 sector

我尝试了.filter() 功能,但没有让它工作:

const filteredCards = objArray.filter(card =>{
    return card.scope   === compare.scope
        && card.sector  === compare.sector;
});

【问题讨论】:

  • 你能告诉我们你试过的代码吗? .filter() 应该可以工作。
  • @Halcyon,我已经更新了我的答案。

标签: javascript loops ecmascript-6


【解决方案1】:

请试试这个代码。

const compare = {scope: "xx"};

const objArray = [
    {scope: "xx", sector: "yy", status: "pending", country: "USA"},
    {scope: "zz", sector: "yy", status: "pending", country: "USA"},
    {scope: "xx", sector: "yy", status: "pending", country: "USA"}
];


var filter_result = objArray.filter(function(item) {
  for (var key in compare) {
    if (item[key] === undefined || item[key] != compare[key])
      return false;
  }
  return true;
});

console.log(filter_result)

【讨论】:

    【解决方案2】:

    过滤器是可行的方法,但我们也可以使测试动态化,而不是对相关字段进行硬编码。让我们编写一个函数,该函数接受数据数组并按查询对象进行过滤,只返回数组中与查询对象中的每个属性都有匹配值的项:

    const filterByQuery = (data, query) => 
      data.filter(e => Object.entries(query).every(([k, v]) => e[k] === v))
    ;
    
    const data = [
      {scope: "xx", sector: "yy", status: "pending", country: "USA"},
      {scope: "zz", sector: "yy", status: "pending", country: "USA"},
      {scope: "xx", sector: "yy", status: "pending", country: "USA"}
    ];
    
    [
      {scope: "xx", sector: "yy"},
      {scope: "xx"},
      {scope: "yy"},
    ].forEach(query => console.log(filterByQuery(data, query)));

    【讨论】:

    • 如果你试过的话,可以肯定你可以把它放在一条线上;)
    • 也许在你的显示器上!
    • “也许在你的显示器上!”罗弗。在某些单一用例中,单行代码很好,但是,这里的可读性更好。
    • 你的氛围不对。我认为单行文字对公众的可读性较差。此外,它们的可重用性较低。
    • @ggorlen 实际上,由于与undefined 的直接比较,这个答案在 1995 年是有问题的。貌似现在允许了,今天之前我不知道stackoverflow.com/questions/2778901/…
    【解决方案3】:

    我认为问题在于您的过滤器具有可选字段,因此如果未在过滤器中定义字段,则任何值都可以。我认为这会奏效:

    const filteredCards = objArray.filter(card =>{
        return (typeof compare.scope === "undefined" || card.scope === compare.scope)
            && (typeof compare.sector === "undefined" || card.sector === compare.sector)
            && (typeof compare.status === "undefined" || card.status === compare.status)
            && (typeof compare.country === "undefined" || card.country === compare.country);
    });
    

    过滤器没有为字段指定值,或者值匹配。对每个字段重复。

    【讨论】:

    • 我也是这么想的。您可以使用in 运算符以更短的方式编写,例如!'scope' in compare || ...
    • @marekful 哦,这太棒了。我老了=)
    • 我们确定需要对所有相关字段进行硬编码吗?好像和this一样的场景@
    • @ggorlen 这取决于。如果您只拥有 4 个字段,那么任何一种方式都可以。 Glen 的 if-else 树将呈指数增长,而此解决方案是线性的。我主要选择了这种逐字编写过滤器的方式来解释发生了什么。对于像(([k, v]) => e[k] === v) 这样深奥的东西,我必须阅读它两次以确保它正在做我认为它正在做的事情。而且您必须检查您是否在过滤器上eaching,而不是数据等。我认为阅读起来并不好。此外,我的 linting 工具会给你一个大胖子 no .. 所以 xD
    • 当然,这是有效的,但抛开复杂性不谈,函数需要在对象发生变化的任何时候重写,而且我们遇到了一个大的条件,而 linter 也正确地抱怨了这个条件。在这种情况下,我的偏好是将其写成“香草”风格,但仍不使用 here 所做的文字。我并没有真正嫁给现代 JS,但我也不介意。
    猜你喜欢
    • 2015-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多