代码之家  ›  专栏  ›  技术社区  ›  Ravi Sevta

投影JavaScript对象字段的最佳方法是什么?

  •  8
  • Ravi Sevta  · 技术社区  · 6 年前

    我必须将javascript的一些字段投影到新对象。

    例如,我有一个below对象

    var obj = { fn : 'Abc', 
                ln : 'Xyz', 
                id : 123, 
                nt : 'Note', 
                sl : 50000}
    

    我希望新对象包含 fn and id

    var projectedObj = { fn : 'Abc', id : 123 }
    

    基于投影

    var projection = { fn : 1, id : 1 }
    

    像这样的

    var projectedObj = project(obj, projection);
    

    那么,做这件事的最佳方式或优化方式是什么呢。

    5 回复  |  直到 6 年前
        1
  •  4
  •   ayushgp    6 年前

    只需在投影对象中循环并投影关键点即可。例如

    function project(obj, projection) {
        let projectedObj = {}
        for(let key in projection) {
            projectedObj[key] = obj[key];
        }
        return projectedObj;
    }
    
        2
  •  4
  •   Hassan Imam Ravi kant    6 年前

    您可以使用 array#reduce 并遍历投影对象的所有键,并基于该键从原始对象中提取值并创建新对象。

    var project = (o, p) => {
      return Object.keys(p).reduce((r,k) => {
        r[k] = o[k] || '';
        return r;
      },{});
    }
    
    var obj = { fn : 'Abc', ln : 'Xyz', id : 123,  nt : 'Note', sl : 50000};
    var projection = { fn : 1, id : 1 };
    var projectedObj = project(obj, projection);
    console.log(projectedObj);

    您还可以使用 array#map 具有 Object#assign 创建新对象。

    var project = (o, p) => {
      return Object.assign(...Object.keys(p).map(k => ({[k]: o[k]})));
    }
    
    var obj = { fn : 'Abc', ln : 'Xyz', id : 123,  nt : 'Note', sl : 50000};
    var projection = { fn : 1, id : 1 };
    var projectedObj = project(obj, projection);
    console.log(projectedObj);
        3
  •  1
  •   guijob    6 年前

    你可以 reduce 你的 projection 按键返回返回 obj 值为:

    var obj = { fn : 'Abc', ln : 'Xyz', id : 123, nt : 'Note', sl : 50000}
    var projection = { fn : 1, id : 1 }
    
    function project(obj, projection) {
      return Object.keys(projection).reduce((a, e) => { a[e] = obj[e]; return a; }, {});
    }
    
    console.log(project(obj, projection));
        4
  •  0
  •   GuiRitter    5 年前

    我就是这样做的。它可以处理嵌套对象,但可能无法处理可以是值或对象的属性。

    let entity = {
        timeStamp: "1970-01-01T00:00:00.000Z",
        value: 1,
        itemList: [
            {
                amount: 1,
                product: {
                    name: "Product 0",
                    _links: { self: { href: "https://example.com:8080/api/entityA/1" } }
                },
                value: 1,
                flag: false,
                _links: { self: { href: "https://example.com:8080/api/entityB/1" } }
            }
        ],
        summerTime: false,
        parent: {
            grandParentA: {
                name: "Grand Parent 0",
                _links: { self: { href: "https://example.com:8080/api/entityC/1" } }
            },
            grandParentB: null,
            name: "Parent 0",
            _links: { self: { href: "https://example.com:8080/api/entityD/1" } }
        },
        _links: { self: { href: "https://example.com:8080/api/entityE/1" } }
    };
    
    let entityProjection = {
        parent: {
            grandParentA: {
                _links: { self: { href: false } }
            },
            grandParentB: {
                _links: { self: { href: false } }
            },
            _links: { self: { href: false } }
        },
        _links: { self: { href: false } }
    }
    
    const project = (object, projection) => {
        return Object.keys(projection).reduce((a, e) => ({ ...a, [e]: object[e] ? (projection[e] ? project(object[e], projection[e]) : object[e]) : object[e] }), {});
    }
    
    console.log(project(entity, entityProjection));
        5
  •  0
  •   Tore Aurstad    5 年前

    作为一种不传递投影对象,而是将要投影的属性列为逗号分隔字符串的替代方法,此模块可以做到这一点。请注意,此模块支持的不是对象,而是数组。

        var linqmodule = (function() {
      projection = function(members) {
        var membersArray = members.replace(/s/g, "").split(",");
        var projectedObj = {};
    
        for (var i = 0; i < this.length; i++) {
          for (var j = 0; j < membersArray.length; j++) {
            var key = membersArray[j];
            if (j === 0) {
              projectedObj[i] = {};
            }
            projectedObj[i][key] = this[i][key];
          }
        }
    
        return projectedObj;
      };
      Array.prototype.select = projection;
    
      dumpmethod = function(arrayobj) {
        var result = "";
        result += "[";
    
        for (var i = 0; i < Object.keys(arrayobj).length; i++) {
          var membersArray = Object.keys(arrayobj[i]);
          for (var j = 0; j < membersArray.length; j++) {
            if (j === 0) {
              result += "{";
            }
            var key = membersArray[j];
            result +=
              "key: " +
              key +
              " , value: " +
              arrayobj[i][key] +
              (j < membersArray.length - 1 ? " , " : "");
            if (j === membersArray.length - 1) {
              result +=
                "}" + (i < Object.keys(arrayobj).length - 1 ? "," : "") + "\n";
            }
          }
        }
        result += "]";
    
        return result;
      };
    
      return {
        dump: dumpmethod
      };
    })();
    

    要投影Json对象数组,可以使用以下示例作为指导:

    var someCountries = [
              { country: "Norway", population: 5.2, code: "NO" },
              { country: "Finland", population: 5.5, code: "SU" },
              { country: "Iceland", population: 0.4, code: "IC" },
              { country: "Sweden", population: 10.2, code: "SW" }
            ];
    var result = someNums.select("country,population");
    console.log(linqmodule.dump(result));
    

    然后,生成的数组包含投影结果(并复制到新数组中),而不包含字段“code”。

    这并没有回答这个问题,因为它询问的是单个对象和投影对象,但它显示了如何使用对象数组实现相同的效果(数组中的每个对象都具有相同的字段)。许多人会发现它对类似的场景很有用。