【问题标题】:count filled fields in an nested object js计算嵌套对象js中的填充字段
【发布时间】:2021-07-26 16:10:26
【问题描述】:

我想计算一个嵌套对象中有多少填充字段

示例:

const data = {
  name: 'Alex',
  lastName: '',
  age: 24,
  lang: { lang1: 'fr', lang2: 'en' },
  courses: { c1: '', c2: 'math', c3: '' },
  books: { book1: '', book2: 'book2' },
};

结果应该是:6(Alex,24,fr,en,math,book2)

【问题讨论】:

  • 到目前为止你尝试过什么?具体问题出在哪里?

标签: javascript reactjs count nested-object


【解决方案1】:

仅适用于嵌套对象。

const data = {
  name: 'Alex',
  lastName: '',
  age: 24,
  lang: { lang1: 'fr', lang2: 'en' },
  courses: { c1: '', c2: 'math', c3: '' },
  books: { book1: '', book2: 'book2' },
};

let count = 0;

const checkEmptyField = (obj) => {
  Object.values(obj).forEach((value) => {
    if (typeof value !== 'object' && value !== '') count++;
    if (typeof value === 'object') {
      checkEmptyField(value);
    }
  });
};

checkEmptyField(data);

console.log(count); // logs 6

【讨论】:

    【解决方案2】:

    const data = {
      name: 'Alex',
      lastName: '',
      age: 24,
      lang: { lang1: 'fr', lang2: 'en' },
      courses: { c1: '', c2: 'math', c3: '' },
      books: { book1: '', book2: 'book2' },
    }
    
    const isObject = o => typeof o === 'object' && o !== null
    const calcFilled = o => Object.entries(o)
        .reduce((acc, [k, v]) => {
            if (isObject(v)) acc += calcFilled(v)
            else if (v) acc++
            return acc
        }, 0)
    console.log(calcFilled(data))

    【讨论】:

      【解决方案3】:

      正如在对您的问题的评论中已经说过的那样,在您陷入困境之前展示您的进度会更好。 :) 这是我的看法。

      const data = {
        name: 'Alex',
        lastName: '',
        age: 24,
        lang: { lang1: 'fr', lang2: 'en' },
        courses: { c1: '', c2: 'math', c3: '' },
        books: { book1: '', book2: 'book2' },
      };
      
      const countElements = (obj) => {
        // variable for counting element
        let validValueCount = 0;
      
        // get values for object
        const values = Object.values(obj);
      
        // filter out falsy values
        const validValues = values.filter((el) => !!el);
      
        // iterate through all valid values, count non-objects and recursively call this function for objects
        validValues.map((el) => {
          validValueCount =
            validValueCount + (Object.prototype.toString.call(el) === "[object Object]" ? countElements(el) : 1);
        });
      
        // return sum of all counted values
        return validValueCount;
      };
      const ans = countElements(data);
      console.log(ans);

      【讨论】:

      • 感谢 @charmful0x 改进答案(使用 Object.prototype.toString.call 而不是typof)。数组的例子让我们明白为什么它这么 Object.prototype.toString.call([]) -> "[object Array]"
      【解决方案4】:

      您可以使用递归方法减少对象中的值。

      const
          count = object => Object
              .values(object)
              .reduce((s, v) => s + (v && typeof v === 'object'
                  ? count(v)
                  : +!!v
              ), 0),
          data = { name: 'Alex', lastName: '', age: 24, lang: { lang1: 'fr', lang2: 'en' }, courses: { c1: '', c2: 'math', c3: '' }, books: { book1: '', book2: 'book2' } };
          
      console.log(count(data));

      【讨论】:

        【解决方案5】:

        我从另一个SO post借了travese

        function traverse(o,func) {
            for (var i in o) {
                func.apply(this,[i,o[i]]);  
                if (o[i] !== null && typeof(o[i])=="object") {
                    //going one step down in the object tree!!
                    traverse(o[i],func);
                }
            }
        }
        

        所以现在我们可以这样做了:

        const data = {
            name: 'Alex',
            lastName: '',
            age: 24,
            lang: { lang1: 'fr', lang2: 'en' },
            courses: { c1: '', c2: 'math', c3: '' },
            books: { book1: '', book2: 'book2' },
        };
        
        function getCount(obj) {
            // Determine if a value is 'filled'
            let isFilled = (value) => value !== '' && typeof value !== 'object'
        
            let count = 0
            traverse(data, (key, value) => {
                if (isFilled(value))
                    count++
            })
            return count
        }
        
        let result = getCount(data)
        

        【讨论】:

          猜你喜欢
          • 2018-10-15
          • 2017-10-03
          • 1970-01-01
          • 1970-01-01
          • 2021-04-21
          • 1970-01-01
          • 2014-07-28
          • 1970-01-01
          • 2019-09-23
          相关资源
          最近更新 更多