【问题标题】:How to get a subset of a javascript object's properties excluding undefined or null properties如何获取 javascript 对象属性的子集,不包括未定义或空属性
【发布时间】:2021-01-18 05:07:02
【问题描述】:

我可以拥有不同版本的对象:

myObject1 = { 
  color: 'red',
  size : 'big',
  name : 'Beautiful red',
  count: 2
};

myObject2 = { 
  color: 'blue',
  name : 'Awesome blue',
  count : null
};

我需要一个助手来只保留我想要且存在的价值:

function myHelper() {
   ?????
}


myHelper(myObject1, ['color','size','count']) // => { color: 'red', size : 'big', count:2}
myHelper(myObject2, ['color','size','count']) // => { color: 'blue'}

有人已经创建了吗?

【问题讨论】:

    标签: javascript clone helper


    【解决方案1】:
    function myHelper (sourceObj, [...keys]) {
      let objSubset = Object.entries(sourceObj)
        .filter(([key]) => keys.includes(key))
        .filter(([, value]) => value !== undefined && value !== null)
        .reduce((newObj, [key, val]) => Object.assign(newObj, { [key]: val }), {});
      return objSubset
    }
    
    myObject1 = { 
      color: 'red',
      size : 'big',
      name : 'Beautiful red',
      count: 2
    };
    
    myObject2 = { 
      color: 'blue',
      name : 'Awesome blue',
      count : null
    };
    
    let x = myHelper(myObject1, ['color','size','count']);
    let y = myHelper(myObject2, ['color','size','count']);
    
    console.log(x)
    console.log(y)
    

    该函数不会返回具有未定义值和空值的对象,但仍会返回具有0、空字符串""Boolean 值的对象。

    【讨论】:

      【解决方案2】:

      这里发布的一些答案没有明确检查undefinednull,因此如果属性值为空字符串""0,它们也会被过滤,我'我的猜测不是你想要的。

      您可以使用.getOwnPropertyNames.reduce 来过滤您想要的属性。

      function keep(obj = {}, props = []) {
        return Object.getOwnPropertyNames(obj).reduce((acc, prop) => {
          if (obj[prop] !== undefined && obj[prop] !== null && props.includes(prop)) {
            return { ...acc, [prop]: obj[prop] };
          }
      
          return acc;
        }, {});
      }
      
      const cleanedObj = keep({ color: undefined, size: null, count: 0, age: 20 }, [
        "color",
        "size",
        "count",
        "age",
      ]);
      
      console.log(cleanedObj); // { count: 0, age: 20 }

      【讨论】:

        【解决方案3】:

        在使用Object.fromEntrieshere之前检查浏览器兼容性


        您可以使用 Object.entries 循环对象 entries[key, value] 对)和 filter 对象 key k 如果它是在提供的数组中(使用Set 以加快查找速度)和不是null 的值v

        然后将那些 array 条目传递给Object.fromEntries 并将其作为对象获取:

        myObject1 = {
          color: 'red',
          size: 'big',
          name: 'Beautiful red',
          count: 2
        };
        myObject2 = {
          color: 'blue',
          name: 'Awesome blue',
          count: null
        };
        function myHelper(obj, arr) {
          return Object.fromEntries(
            Object.entries(obj)
            .filter(([k, v]) => new Set(arr).has(k) && v !== null)
          );
        }
        console.log(myHelper(myObject1, ['color', 'size', 'count']))
        console.log(myHelper(myObject2, ['color', 'size', 'count']))

        另一种选择是循环遍历arrfilter 中的给定键,这些键存在于给定的obj 中,而不是null

        然后将map 转换为[key, value] 对数组,并将其作为参数提供给Object.fromEntries 以作为对象输出:

        myObject1 = {
          color: 'red',
          size: 'big',
          name: 'Beautiful red',
          count: 2
        };
        myObject2 = {
          color: 'blue',
          name: 'Awesome blue',
          count: null
        };
        function myHelper(obj, arr) {
          return Object.fromEntries(
           arr.filter(k => obj[k]).map(k => [k, obj[k]])
          );
        }
        console.log(myHelper(myObject1, ['color', 'size', 'count']))
        console.log(myHelper(myObject2, ['color', 'size', 'count']))

        【讨论】:

          【解决方案4】:

          您可以.map() 覆盖您的密钥数组并基于您的密钥数组构建一个新对象。要从数组构建新对象,您可以将键映射到对象。然后,您可以使用 Object.assign() 将此对象数组合并为一个对象:

          const myObject1 = { color: 'red', size : 'big', name : 'Beautiful red', count: 2 };
          const myObject2 = { color: 'blue', name : 'Awesome blue', count : null };
          
          function myHelper(obj, arr) {
            return Object.assign(
              {}, ...arr.map(k => obj[k] != undefined ? {[k]: obj[k]} : {})
            );
          }
          
          console.log(myHelper(myObject1, ['color','size','count'])); // => { color: 'red', size : 'big', count:2}
          console.log(myHelper(myObject2, ['color','size','count'])); // => { color: 'blue'}

          通过从键构建对象(而不是过滤掉您的输入对象),您无需检查当前条目是否在您的键数组中。

          【讨论】:

            【解决方案5】:

            使用Array.reduce我们可以做到这一点

            let myObject1 = { 
              color: 'red',
              size : 'big',
              name : 'Beautiful red',
              count: 2
            };
            
            let myObject2 = { 
              color: 'blue',
              name : 'Awesome blue',
              count : null
            };
            
            const myHelper = (data, keys) => keys.reduce((res, key) => {
              //check if the data is available in the provided object for the given key, if so add it to the result object.
              if (data[key]) {
                res[key] = data[key]
              };
              return res;
            }, {})
            
            
            console.log(myHelper(myObject1, ['color', 'size', 'count']))
            console.log(myHelper(myObject2, ['color', 'size', 'count']))
            .as-console-wrapper {
              max-height: 100% !important;
            }

            【讨论】:

              【解决方案6】:

              将对象转换为条目并过滤:

              • 对象属性 (key) 存在于所需的密钥列表 (props) 中
              • 值 (val) 不是 null

              const myObject1 = { 
                color: 'red',
                size : 'big',
                name : 'Beautiful red',
                count: 2
              };
              
              const myObject2 = { 
                color: 'blue',
                name : 'Awesome blue',
                count : null
              };
              
              function myHelper(obj, props) {
                return Object.fromEntries(Object.entries(obj)
                  .filter(([key, val]) => props.includes(key) && val != null));
              }
              
              console.log(myHelper(myObject1, ['color','size','count']));
              console.log(myHelper(myObject2, ['color','size','count']));
              .as-console-wrapper { top: 0; max-height: 100% !important; }

              如果您想对此进行优化,您可以通过以下方式将“数组包含”更改为“集合包含”检查:

              const myHelper = (obj, props) => (pSet => Object.fromEntries(Object.entries(obj)
                  .filter(([key, val]) => pSet.has(key) && val != null)))
              (new Set(props));
              

              【讨论】:

              • 短:const myHelper = (obj, props) => Object.fromEntries(Object.entries(obj) .filter(([key, val]) => props.includes(key) && val != null));
              【解决方案7】:

              使用Array.reduce作为键可以简单地完成。

              myObject1 = { 
                color: 'red',
                size : 'big',
                name : 'Beautiful red',
                count: 2
              };
              
              myObject2 = { 
                color: 'blue',
                name : 'Awesome blue',
                count : null
              };
              
              function myHelper(input, keys) {
                const result = keys.reduce((acc, cur) => {
                  if (input[cur]) {
                    acc[cur] = input[cur];
                  }
                  return acc;
                }, {});
                return result;
              }
              
              
              console.log(myHelper(myObject1, ['color','size','count'])); // => { color: 'red', size : 'big', count:2}
              console.log(myHelper(myObject2, ['color','size','count'])); // => { color: 'blue'}

              【讨论】:

                猜你喜欢
                • 2020-01-12
                • 1970-01-01
                • 2021-12-27
                相关资源
                最近更新 更多