【问题标题】:Find property name with filled value from typescript object从打字稿对象中查找具有填充值的属性名称
【发布时间】:2019-12-03 12:19:40
【问题描述】:

我有一组属性名称 (removableWriteOffFields),我需要检查 JSON 对象中的这些属性是否具有填充值。之后,我需要将填充属性列表写入填充字段变量。我尝试将对象转换为值数组及其属性名称,但是这个对象是结构化的,所以我不能轻易地将它转换为我要检查的数组。

我试过这个解决方案

    let filledFields: string[] = [];
    const removFields: string[] = this.individualPartyConfiguration
                .removableWriteOffFields;
    const partyArr = helper.filter(function(abc) {
                return isString(abc[1]); 
            });
    removFields.forEach(element => {
                const index = partyArr.findIndex(e => e[0] === element);
                if (
                    partyArr[index][1] !== (undefined && null) &&
                    partyArr[index][1].length !== 0
                ) {
                    filledFields.push(element);
                }
            });

removableWriteOffFields 包含我需要检查的所有属性名称。

        "removableWriteOffFields": [
        "flowerSelfAssessment",
        "phoneNumber",
        "gender",
        "birthDate",
        "age",
        "jobTitle",
        "jobFamily",
        "city",
        "region",
        "country",
        "parentOrganizationName"
    ]

对象示例:

{
  "_id": "6224da36-9a28-4bed-a316-f910d1c1df90",
  "metadata": {
    "trackingInfo": {
      "initiator": "EntityFactory",
      "created": "2019-07-16T08:13:30.044Z",
      "creator": "EntityFactory",
      "modified": "2019-07-16T08:13:30.044Z",
      "version": 0
    },
    "type": "IndividualParty",
    "valid": true
  },
  "externalPartyId": "P010",
  "locations": [
    {
      "_id": "986b7bbe-6138-4897-8b70-22d89126fc03",
      "metadata": {
        "trackingInfo": {
          "initiator": "EntityFactory",
          "created": "2019-07-16T08:13:30.044Z",
          "creator": "EntityFactory",
          "modified": "2019-07-16T08:13:30.044Z",
          "version": 0
        },
        "type": "EmailAddressLocation",
        "valid": true
      },
      "valid": true,
      "primary": true,
      "emailAddress": "jan.Kina@luth.com"
    }
  ],
  "partyProfiles": [
    {
      "_id": "877b183a-0610-42d8-9899-3722639d2f89",
      "metadata": {
        "trackingInfo": {
          "initiator": "EntityFactory",
          "created": "2019-07-16T08:13:30.044Z",
          "creator": "EntityFactory",
          "modified": "2019-07-16T08:13:30.044Z",
          "version": 0
        },
        "type": "LutherProUserPartyProfile",
        "valid": true
      },
      "agile": false,
      "agileShare": 0,
      "parentOrganizationName": "Apo Czech, a.s.",
      "background": {
        "defaultLink": "https://s3-eu-wea.com/Luideo_1.mp4.png",
        "videoLink": "httpseo_1.mp4"
      },
      "contractStart": "2019-07-16T08:13:30.044Z",
      "avatarLink": "",
      "nickname": "Jan.Kina",
      "jobTitle": "Backend developer",
      "preferredLang": "en-US",
      "defaultPartyRoleId": "2e71ee52-0f24-88ee-5ec7-8b9f5c1df6a3"
    }
  ],
  "partyRoleIds": [
    "510d02d1-41a9-c139-f8aa-59c363eb0b2c"
  ],
  "birthDate": "2019-01-15T00:00:00.000Z",
  "firstName": "Jan",
  "formattedName": "Jan Kina",
  "formattedPhoneticName": "Jan Kina",
  "gender": "male",
  "headline": "headline",
  "lastName": "Kina",
  "middleNames": [],
  "phoneticFirstName": "Jan",
  "phoneticLastName": "Kina",
  "summary": "Summary of this user..."
}

解决方案

function pick<T>(party: T, removFields: string[], val: string[]) {
            let key: keyof T;

            Object.keys(party).forEach(item => {
                key = item as (keyof T);
                if (removFields.includes(key as string)) {
                    val.push(key as string);
                    logger.info(`val: ${JSON.stringify(val, undefined, 2)}`);
                } else if (typeof party[key] === 'object') {
                    pick<T[keyof T]>(party[key], removFields, val);
                }
            });

            return val;
        }

【问题讨论】:

标签: javascript json typescript object


【解决方案1】:

这是一个使用递归的更简单的解决方案。

const pick = (obj, arr, def={}) => {
  let val = def;
  Object.keys(obj).forEach((item, curr) => {
    if(arr.includes(item)) {
      val[item] = obj[item];
    } else if(typeof obj[item] === 'object') {
      pick(obj[item], arr, val)
    }
  });
  return val
}

let arr = [
  "flowerSelfAssessment",
  "phoneNumber",
  "gender",
  "birthDate",
  "age",
  "jobTitle",
  "jobFamily",
  "city",
  "region",
  "country",
  "parentOrganizationName"
    ]
    
let obj = {
  "_id": "6224da36-9a28-4bed-a316-f910d1c1df90",
  "metadata": {
    "trackingInfo": {
      "initiator": "EntityFactory",
      "created": "2019-07-16T08:13:30.044Z",
      "creator": "EntityFactory",
      "modified": "2019-07-16T08:13:30.044Z",
      "version": 0
    },
    "type": "IndividualParty",
    "valid": true
  },
  "externalPartyId": "P010",
  "locations": [
    {
      "_id": "986b7bbe-6138-4897-8b70-22d89126fc03",
      "metadata": {
        "trackingInfo": {
          "initiator": "EntityFactory",
          "created": "2019-07-16T08:13:30.044Z",
          "creator": "EntityFactory",
          "modified": "2019-07-16T08:13:30.044Z",
          "version": 0
        },
        "type": "EmailAddressLocation",
        "valid": true
      },
      "valid": true,
      "primary": true,
      "emailAddress": "jan.Kina@luth.com"
    }
  ],
  "partyProfiles": [
    {
      "_id": "877b183a-0610-42d8-9899-3722639d2f89",
      "metadata": {
        "trackingInfo": {
          "initiator": "EntityFactory",
          "created": "2019-07-16T08:13:30.044Z",
          "creator": "EntityFactory",
          "modified": "2019-07-16T08:13:30.044Z",
          "version": 0,
        },
        "type": "LutherProUserPartyProfile",
        "valid": true
      },
      "agile": false,
      "agileShare": 0,
      "parentOrganizationName": "Apo Czech, a.s.",
      "background": {
        "defaultLink": "https://s3-eu-wea.com/Luideo_1.mp4.png",
        "videoLink": "httpseo_1.mp4"
      },
      "contractStart": "2019-07-16T08:13:30.044Z",
      "avatarLink": "",
      "nickname": "Jan.Kina",
      "jobTitle": "Backend developer",
      "preferredLang": "en-US",
      "defaultPartyRoleId": "2e71ee52-0f24-88ee-5ec7-8b9f5c1df6a3"
    }
  ],
  "partyRoleIds": [
    "510d02d1-41a9-c139-f8aa-59c363eb0b2c"
  ],
  "birthDate": "2019-01-15T00:00:00.000Z",
  "firstName": "Jan",
  "formattedName": "Jan Kina",
  "formattedPhoneticName": "Jan Kina",
  "gender": "male",
  "headline": "headline",
  "lastName": "Kina",
  "middleNames": [],
  "phoneticFirstName": "Jan",
  "phoneticLastName": "Kina",
  "summary": "Summary of this user...",
}

const pick = (obj, arr, def={}) => {
	let val = def;
  Object.keys(obj).forEach((item, curr) => {
  	if(arr.includes(item)) {
    	val[item] = obj[item];
    } else if(typeof obj[item] === 'object') {
    	pick(obj[item], arr, val)
    }
  });
  return val
}

console.log(pick(obj, arr))

Typescript 版本(我删除了:let key: keyof IndividualParty; 并更改了let key = item as (keyof IndividualParty));,对我来说效果很好,函数返回带有属性的数组

function pick(party: IndividualParty,removFields: (keyof IndividualParty)[], def?: string[]) {
  let val: string[];
  if (def !== undefined) {
      val = def;
  } else {
      val = [];
  }
  Object.keys(party).forEach(item => {
    let key = item as (keyof IndividualParty);
    if (removFields.includes(key)) {
       val.push(key);
     } else if (typeof party[key] === 'object') {
        pick(party[key], removFields, val);
      }
    });
    return val;
 }
 pick(obj, arr)

【讨论】:

  • 给我看整个代码,你用它来排序这个对象
  • 我也使用了递归,但是它隐藏在迭代器的构造函数中,所以无需考虑或担心。而且它是 100% 兼容的——不要认为任何平台/版本都会有问题。而你只做 1/2 - 我还列出了出现次数 # 的已找到项目,因此很容易检查某些或全部是否存在/不存在。简单地忘记迭代器 IIFE,rest 再简单不过了——你可以通过 2 行代码循环迭代任何 JSON,单行创建迭代器。
【解决方案2】:

在您的 JSON 中添加了一个额外的 parentOrganizationName 记录以显示非唯一键选项:

'use strict';
function test(looking4, json) {
    var it = new JIterator(json);
    var i = 0;
    var occurences = {}, found = {};
    for (var i in looking4) {
        var key = looking4[i];
        occurences[key] = 0;
    }
    do {
        var item = it.Current();
        if (looking4.indexOf(item.key) > -1) {
            occurences[item.key]++;
            if (found[item.key]) {
                found[item.key] = [found[item.key]];
                found[item.key].push(item.value);
            } else {
                found[item.key] = item.value;
            }

        }
    } while (it.DepthFirst());
    console.log(JSON.stringify(occurences, null, 4));
    console.log(JSON.stringify(found, null, 4));
}

var search4 = {
    "removableWriteOffFields": [
        "flowerSelfAssessment",
        "phoneNumber",
        "gender",
        "birthDate",
        "age",
        "jobTitle",
        "jobFamily",
        "city",
        "region",
        "country",
        "parentOrganizationName"
    ]
};

var json = {
    "_id": "6224da36-9a28-4bed-a316-f910d1c1df90",
    "metadata": {
        "trackingInfo": {
            "initiator": "EntityFactory",
            "created": "2019-07-16T08:13:30.044Z",
            "creator": "EntityFactory",
            "modified": "2019-07-16T08:13:30.044Z",
            "version": 0
        },
        "type": "IndividualParty",
        "valid": true
    },
    "externalPartyId": "P010",
    "locations": [
        {
            "_id": "986b7bbe-6138-4897-8b70-22d89126fc03",
            "metadata": {
                "trackingInfo": {
                    "initiator": "EntityFactory",
                    "created": "2019-07-16T08:13:30.044Z",
                    "creator": "EntityFactory",
                    "modified": "2019-07-16T08:13:30.044Z",
                    "version": 0
                },
                "type": "EmailAddressLocation",
                "valid": true
            },
            "valid": true,
            "primary": true,
            "emailAddress": "jan.Kina@luth.com"
        }
    ],
    "partyProfiles": [
        {
            "_id": "877b183a-0610-42d8-9899-3722639d2f89",
            "metadata": {
                "trackingInfo": {
                    "initiator": "EntityFactory",
                    "created": "2019-07-16T08:13:30.044Z",
                    "creator": "EntityFactory",
                    "modified": "2019-07-16T08:13:30.044Z",
                    "version": 0
                },
                "type": "LutherProUserPartyProfile",
                "valid": true
            },
            "agile": false,
            "agileShare": 0,
            "parentOrganizationName": "Apo Czech, a.s.",
            "background": {
                "defaultLink": "https://s3-eu-wea.com/Luideo_1.mp4.png",
                "videoLink": "httpseo_1.mp4"
            },
            "contractStart": "2019-07-16T08:13:30.044Z",
            "avatarLink": "",
            "nickname": "Jan.Kina",
            "jobTitle": "Backend developer",
            "preferredLang": "en-US",
            "defaultPartyRoleId": "2e71ee52-0f24-88ee-5ec7-8b9f5c1df6a3"
        }
    ],
    "partyRoleIds": [
        "510d02d1-41a9-c139-f8aa-59c363eb0b2c"
    ],
    "birthDate": "2019-01-15T00:00:00.000Z",
    "firstName": "Jan",
    "formattedName": "Jan Kina",
    "formattedPhoneticName": "Jan Kina",
    "gender": "male",
    "headline": "headline",
    "lastName": "Kina",
    "middleNames": [],
    "phoneticFirstName": "Jan",
    "phoneticLastName": "Kina",
    "summary": "Summary of this user...",
    "parentOrganizationName": "Apo Czech, a.s. 2nd"
};

// https://github.com/eltomjan/ETEhomeTools/blob/master/HTM_HTA/JSON_Iterator_IIFE.js
var JNode = (function (jsNode) {

    function JNode(_parent, _pred, _key, _value) {
        this.parent = _parent;
        this.pred = _pred;
        this.node = null;
        this.next = null;
        this.key = _key;
        this.value = _value;
    }

    return JNode;
})();

var JIterator = (function (json) {
    var root, current, maxLevel = -1;

    function JIterator(json, parent) {
        if (parent === undefined) parent = null;
        var pred = null, localCurrent;
        for (var child in json) {
            var obj = json[child] instanceof Object;
            if (json instanceof Array) child = parseInt(child); // non-associative array
            if (!root) root = localCurrent = new JNode(parent, null, child, json[child]);
            else {
                localCurrent = new JNode(parent, pred, child, obj ? ((json[child] instanceof Array) ? [] : {}) : json[child]);
            }
            if (pred) pred.next = localCurrent;
            if (parent && parent.node == null) parent.node = localCurrent;
            pred = localCurrent;
            if (obj) {
                var memPred = pred;
                JIterator(json[child], pred);
                pred = memPred;
            }
        }
        if (this) {
            current = root;
            this.Level = 0;
        }
    }

    JIterator.prototype.Current = function () { return current; }
    JIterator.prototype.Parent = function () {
        var retVal = current.parent;
        if (retVal == null) return false;
        this.Level--;
        return current = retVal;
    }
    JIterator.prototype.Pred = function () {
        var retVal = current.pred;
        if (retVal == null) return false;
        return current = retVal;
    }
    JIterator.prototype.Node = function () {
        var retVal = current.node;
        if (retVal == null) return false;
        this.Level++;
        return current = retVal;
    }
    JIterator.prototype.Next = function () {
        var retVal = current.next;
        if (retVal == null) return false;
        return current = retVal;
    }
    JIterator.prototype.Key = function () { return current.key; }
    JIterator.prototype.KeyDots = function () { return (typeof (current.key) == "number") ? "" : (current.key + ':'); }
    JIterator.prototype.Value = function () { return current.value; }
    JIterator.prototype.Reset = function () {
        current = root;
        this.Level = 0;
    }
    JIterator.prototype.RawPath = function () {
        var steps = [], level = current;
        do {
            if (level != null && level.value instanceof Object) {
                steps.push(level.key + (level.value instanceof Array ? "[]" : "{}"));
            } else {
                if (level != null) steps.push(level.key);
                else break;
            }
            level = level.parent;
        } while (level != null);
        var retVal = "";
        retVal = steps.reverse();
        return retVal;
    }
    JIterator.prototype.Path = function () {
        var steps = [], level = current;
        do {
            if (level != null && level.value instanceof Object) {
                var size = 0;
                var items = level.node;
                if (typeof (level.key) == "number") steps.push('[' + level.key + ']');
                else {
                    while (items) {
                        size++;
                        items = items.next;
                    }
                    var type = (level.value instanceof Array ? "[]" : "{}");
                    var prev = steps[steps.length - 1];
                    if (prev && prev[0] == '[') {
                        var last = prev.length - 1;
                        if (prev[last] == ']') {
                            last--;
                            if (!isNaN(prev.substr(1, last))) {
                                steps.pop();
                                size += '.' + prev.substr(1, last);
                            }
                        }
                    }
                    steps.push(level.key + type[0] + size + type[1]);
                }
            } else {
                if (level != null) {
                    if (typeof (level.key) == "number") steps.push('[' + level.key + ']');
                    else steps.push(level.key);
                }
                else break;
            }
            level = level.parent;
        } while (level != null);
        var retVal = "";
        retVal = steps.reverse();
        return retVal;
    }
    JIterator.prototype.DepthFirst = function () {
        if (current == null) return 0; // exit sign
        if (current.node != null) {
            current = current.node;
            this.Level++;
            if (maxLevel < this.Level) maxLevel = this.Level;
            return 1; // moved down
        } else if (current.next != null) {
            current = current.next;
            return 2; // moved right
        } else {
            while (current != null) {
                if (current.next != null) {
                    current = current.next;
                    return 3; // returned up & moved next
                }
                this.Level--;
                current = current.parent;
            }
        }
        return 0; // exit sign
    }
    JIterator.prototype.BreadthFirst = function () {
        if (current == null) return 0; // exit sign
        if (current.next) {
            current = current.next;
            return 1; // moved right
        } else if (current.parent) {
            var level = this.Level, point = current;
            while (this.DepthFirst() && level != this.Level);
            if (current) return 2; // returned up & moved next
            do {
                this.Reset();
                level++;
                while (this.DepthFirst() && level != this.Level);
                if (current) return 3; // returned up & moved next
            } while (maxLevel >= level);
            return current != null ? 3 : 0;
        } else if (current.node) {
            current = current.node;
            return 3;
        } else if (current.pred) {
            while (current.pred) current = current.pred;
            while (current && !current.node) current = current.next;
            if (!current) return null;
            else return this.DepthFirst();
        }
    }

    return JIterator;
})();

// Run demo
test(search4.removableWriteOffFields, json);

【讨论】:

    猜你喜欢
    • 2019-06-13
    • 1970-01-01
    • 2019-04-20
    • 1970-01-01
    • 1970-01-01
    • 2019-10-03
    • 2020-12-17
    • 1970-01-01
    • 2020-01-19
    相关资源
    最近更新 更多