首页 > 解决方案 > javascript json 查找每个给定路径的值;处理错误

问题描述

下面是我收到的一个 JSON 对象作为响应。几点说明:

JSON:

{
    "company": {
        "result": [
            {
                "profile": {
                    "address": "One Microsoft Way",
                    "bosses": [
                        {
                            "name": "Mr. Satya  Nadella",
                            "age": 53,
                            "totalPay": {
                                "raw": 13603180,
                                "fmt": "13.6M",
                                "longFmt": "13,603,180"
                            }
                        },
                        {
                            "name": "Mr. Bradford L. Smith",
                            "age": 61,
                            "title": "Pres & Chief Legal Officer",
                            "totalPay": {
                                "raw": 4265576,
                                "fmt": "4.27M",
                                "longFmt": "4,265,576"
                            }
                        }
                    ],
                    "auditRisk": 1,
                },
                "statistics": {
                    "enterpriseValue": {
                        "raw": 1570244395008,
                        "fmt": "1.57T",
                    },
                    "profitMargins": {
                        "raw": 0.32285
                    },
                    "financialCurrency": "USD"
                }
            }
        ],
        "error": null
    }
}

我想:

脚本

var json = JSON.parse(response.getContentText());

var paths = arr[
    "profile/address",                 <-- return the value
    "profile/sector",                  <-- does not exist, return false
    "profile/bosses/name",             <-- is an array with 2 elements, return both names
    "profile/bosses/1/age"             <-- only return age of second element
    "statistics/enterpriseValue/fmt",  <-- return the value
    "profitMargins/fmt",               <-- does not exist, return false
]

预期输出:

One Microsoft Way
false
Mr. Satya Nadella
Mr. Bradford L. Smith
53
false

我现在尝试了很长一段时间,但我感到困惑。你能帮我吗?

for (path in paths) {
    var steps = path.split('/')
    
    for (step in steps) {
        if (step.hasOwnProperty(steps[step+1])) {
            if (typeof path[step] === "object") {
                // array, so loop again?
            }
            if (typeof path[step] === undefined) {
                // value doesn't exist?
                
                return false;
            }
            if (typeof path[step] !== undefined) {
                return path[step].value;
            }
        }
    }
}

标签: javascriptjson

解决方案


我认为有一些事情要先考虑,所以我只开始在以下路径搜索对象

getPath( data, 'company/result/0' )

这让我更容易开始搜索您指定的路径。

我认为您为属性选择的语法可能不是最简单的语法,因为决定是搜索所有元素还是只搜索数组中的单个项目有点困难(例如,您将寻找类似length项目的东西)。

此结果中仍然存在子数组,但如果您愿意,可以将结果展平。

const data = {
    "company": {
        "result": [
            {
                "profile": {
                    "address": "One Microsoft Way",
                    "bosses": [
                        {
                            "name": "Mr. Satya  Nadella",
                            "age": 53,
                            "totalPay": {
                                "raw": 13603180,
                                "fmt": "13.6M",
                                "longFmt": "13,603,180"
                            }
                        },
                        {
                            "name": "Mr. Bradford L. Smith",
                            "age": 61,
                            "title": "Pres & Chief Legal Officer",
                            "totalPay": {
                                "raw": 4265576,
                                "fmt": "4.27M",
                                "longFmt": "4,265,576"
                            }
                        }
                    ],
                    "auditRisk": 1,
                },
                "statistics": {
                    "enterpriseValue": {
                        "raw": 1570244395008,
                        "fmt": "1.57T",
                    },
                    "profitMargins": {
                        "raw": 0.32285
                    },
                    "financialCurrency": "USD"
                }
            }
        ],
        "error": null
    }
};

const pathsToFind = [
  "profile/address",
  "profile/sector",                 
  "profile/bosses/name",            
  "profile/bosses/1/age",            
  "statistics/enterpriseValue/fmt",
  "profitMargins/fmt"
];



function getPath( obj, path ) {
  if (!path || !obj) {
    return null;
  }
  const [currentPath, ...rest] = path.split('/');
  const nextPath = rest.join('/');
  const currentObj = obj[currentPath];
  
  // final path, exit here
  if (nextPath.length === 0) {
    return currentObj;
  }
  
  if (Array.isArray( currentObj )) {
    // does an element exit at the next level
    if ( currentObj[nextPath[0]] ) {
      // will continue reading for 1 element
      return getPath( currentObj, nextPath );
    }
    // return all the subpaths, skip the ones that are falsy
    return currentObj.map( item => getPath( item, nextPath ) ).filter( v => v );
  }
  // get the next part of the object
  return getPath( currentObj, nextPath );
}

function getMatchingValues( obj, paths ) {
  return paths.flatMap( path => getPath( obj, path ) ?? false );
}

console.log( getMatchingValues( getPath( data, 'company/result/0' ), pathsToFind ) );


推荐阅读