【问题标题】:Filtering nested objects Javascript过滤嵌套对象Javascript
【发布时间】:2021-01-15 05:42:11
【问题描述】:

我知道类似的问题,例如here,但我不知道什么应该是一个简单的问题。我正在尝试过滤对象的对象以获得真实值。

const obj = {
  piano: {
    scales: { essential: 1 },
    chords: { essential: 1 },
    triads: { essential: 0 },
  },
  bass: { scales: { essential: 1 }, triads: { essential: 0 } },
};
function getEssential(state) {
  return Object.fromEntries(
    Object.entries(state).filter(([, val]) => val.essential)
  );
}

const resOne = Object.fromEntries(
  Object.entries(obj.piano).filter(([, val]) => val.essential)
);

const resTwo = Object.keys(obj).forEach((el) =>
  Object.entries(obj[el]).filter(([, val]) => val.essential)
);

const resThree = Object.keys(obj).forEach((el) => getEssential(el));

console.log(resOne);
console.log(resTwo);
console.log(resThree);

看到 resOne 提供了所需的输出,但只有一个键(在本例中为piano)。我知道我可以创建一个空数组并添加通过测试的数组,但必须有更有效的方法。

我如何获取一个对象,遍历所有键,应用过滤器并返回相同的对象减去必要的属性!== 1?

当前输出:

{ scales: { essential: 1 }, chords: { essential: 1 } }
undefined
undefined

【问题讨论】:

    标签: javascript object filter


    【解决方案1】:

    您需要嵌套条目的嵌套方法。

    function getEssential(state) {
        return Object.fromEntries(Object
            .entries(state)
            .map(([k, v]) => [k, Object.fromEntries(Object.entries(v).filter(([, val]) => val.essential))])
        );
    }
    
    const obj = {
      piano: {
        scales: { essential: 1 },
        chords: { essential: 1 },
        triads: { essential: 0 },
      },
      bass: { scales: { essential: 1 }, triads: { essential: 0 } },
    };
    
    console.log(getEssential(obj));

    【讨论】:

      【解决方案2】:
      • 使用Object.entries可以获取每个子对象的值,可以使用Array.filter获取过滤后的条目。
      • 之后,使用Object.fromEntries,您可以从过滤的条目中重新生成对象

      const obj = {
        piano: {
          scales: { essential: 1 },
          chords: { essential: 1 },
          triads: { essential: 0 },
        },
        bass: { scales: { essential: 1 }, triads: { essential: 0 } },
      };
      
      const getEssentials = (obj) => {
        const result = {};
        const keys = Object.keys(obj);
        keys.forEach(key => {
          var entries = Object.entries(obj[key]).filter(([subKey, subValue]) => subValue.essential);
          result[key] = Object.fromEntries(entries);
        });
        
        return result;
      };
      
      console.log(getEssentials(obj));

      【讨论】:

      • 谢谢它的工作。如前所述,我知道推送到数组会起作用,但正在寻找一种使用 map 或 reduce 的方法,
      【解决方案3】:

      您可以使用带有for...in 循环的递归方法来执行此操作,并且仅当在某个级别上找到属性essential: 1 时才将属性添加到结果中。

      const obj = {
        piano: { scales: { essential: 1 }, chords: { essential: 1 }, triads: { essential: 0 } },
        bass: { scales: { essential: 1 }, triads: { essential: 0 } },
      };
      
      function filter(obj) {
        const result = {}
      
        for (let i in obj) {
          if (typeof obj[i] === 'object') {
            const val = filter(obj[i])
      
            if (val) {
              result[i] = val;
            }
          } else {
            if (i === 'essential' && obj[i] != 1) {
              return false
            } else {
              result[i] = obj[i]
            }
          }
        }
      
        return result;
      }
      
      console.log(filter(obj))

      【讨论】:

        【解决方案4】:

        const obj = {
          piano: {
            scales: { essential: 1 },
            chords: { essential: 1 },
            triads: { essential: 0 },
          },
          bass: { scales: { essential: 1 }, triads: { essential: 0 } },
        };
        
        const filtered = Object.fromEntries(
          Object.entries(obj)
            .map(e => [e[0], Object.entries(e[1]).reduce((acc, [key, val]) => {
              if (!!val.essential) acc = {...acc, [key]: val}
              return acc
            }, {})]
          )
        )
        
        console.info(filtered)

        【讨论】:

        • 我对此投了反对票,因为它不正确。您正在使用 obj.piano,而它必须与键无关。请参阅 Nina Scholz 的答案。您提供的内容与我的代码相同。
        • @noblerthanoedipus 现在我了解您想要什么,也可以通过迭代根属性轻松修复。查看。对我来说,使用 map 和 reduce 更具可读性。
        猜你喜欢
        • 1970-01-01
        • 2018-09-30
        • 2019-10-15
        • 1970-01-01
        • 2022-06-15
        • 2020-02-01
        • 2020-07-28
        相关资源
        最近更新 更多