在JSON中使用动态多维键/值对 [英] Working With Dynamic Multidimensional key-value pairs in JSON

查看:84
本文介绍了在JSON中使用动态多维键/值对的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个棘手的问题,只能在SO上看到类似但更简单的解决方案.

Having a thorny problem and only see similar but also simpler solutions on SO.

是否可以使用JS/JSON生成动态键和动态值?

Is is possible to generate a dynamic key AND dynamic values using JS/JSON?

例如,假设我有这样的JSON:

For instance, let's say I have JSON like this:

{
    "email": "user@someco.com",
    "firstname": "Bob",
    "lastname": "Smith",
    "company": "ACME",
    "custom": {
        "services": [
            {
                "name": "svc1",
                "desc": "abcdefg",
                "selected": "true",
                "status": "None"
            },
            {
                "name": "svc2",
                "desc": "abcdefg",
                "selected": "true",
                "status": "None"
            },
            {
                "name": "svc3",
                "desc": "abcdefg",
                "selected": "false",
                "status": "None"
            },
            {
                "name": "svc4",
                "desc": "abcdefg",
                "selected": "false",
                "status": "None"
            }
        ],
        "fields": [
            {
                "name": "Products",
                "desc": "abcdef",
                "type": "multi",
                "values": [
                    {
                        "name": "Product1",
                        "desc": "abcdef"
                    },
                    {
                        "name": "Product2",
                        "desc": "abcdef"
                    }
                ],
                "services": [
                    "svc1",
                    "svc2",
                    "svc3"
                ]
            },
            {
                "name": "Wines",
                "desc": "abcdef",
                "type": "multi",
                "values": [
                    {
                        "name": "Wine 1",
                        "desc": "abcdef"
                    }
                ],
                "services": [
                    "svc4"
                ]
            },
            {
                "name": "Fruits",
                "desc": "abcdef",
                "type": "multi",
                "values": [
                    {
                        "name": "Fruit 1",
                        "desc": "abcdef"
                    },
                    {
                        "name": "Fruit 2",
                        "desc": "abcdef"
                    }
                ],
                "services": [
                    "svc4"
                ]
            }
        ]
    }
};

我需要进入各个领域,并针对每个领域(产品,葡萄酒,水果)查看其中是否包含给定的服务,以便我可以回过头来为需要它的每种服务生成产品,葡萄酒或水果.但是我不想重复多次服务名称.生成的JSON应该看起来像这样:

I need to go into the fields and for each field (products, wines, fruits) see if a given service is contained within so that I can go back and generate a product or wine or fruit for each service that requires it. But I don't want to repeat the services names more than once. The resulting JSON should look something like this:

{"svc1":["Products"], "svc2":["Products"], "svc3":["Products"], "svc4":["Fruits", "Wines"]} 

希望是,要在Angular中生成一个动态列表,我可以打开并循环回此JSON,以提取每种产品,水果,葡萄酒和其他产品的值.

The hope would be that to generate a dynamic list in Angular I can just turn and loop back through this JSON, pulling out the values for each product, fruit, wine, whatever.

我一直在尝试很多嵌套的for循环之类的东西,但是每当我向下移动一层以上时,这种动力似乎就停止了.我猜想要实现此目的,我需要在JS Objects和JSON之间切换?

I've been trying a lot of nested for loops and the like but whenever I get more than one layer down the dynamism seems to stop. I'm guessing that for this to work I need to move between JS Objects and JSON?

现在,我正在尝试类似的方法,它不能正常工作,字符串化或否.也许我在JSON和JS对象之间翻转太多了:

Right now I'm trying something like this, which isn't quite working, stringify or no. And maybe I'm flip-flopping too much between JSON and JS Objects:

var outObj = [];    

var fieldItems;
        $.each(jsonObj.custom.fields, function(key, item) {
            fieldItems = item;
            fieldItems.name = item.name;
            $.each(fieldItems.services, function(key, item) {
                var serviceName = item;
//check to see if the serviceName already exists
                if (outObj.indexOf(serviceName) > -1) {
                outObj.serviceName.push(fieldItems.name);
            } else {
                outObj.push(serviceName);
            }

            });
        });

        JSON.stringify(outObj);
        console.log("outObj " + outObj);

我收到无法读取未定义的属性'push'"错误等.似乎可以从单个嵌套循环中做到这一点,但是也许我只需要执行两次遍历即可?还有其他建议吗?

I get "can't read property 'push' of undefined" errors and the like. Seems this should be possible from a single nested loop, but maybe I need to just do two passes? Any other suggestions?

推荐答案

对我来说,这听起来像是过于复杂的解决方案.您可以使用javascript的基本数组方法来过滤出所需的结构.我不确定给出的代码片段中的profiling_value是什么,所以我从OP中的对象结构开始

To me it sounds like overcomplicated solution. You can use basic array methods of javascript to filter out required structure. I am not sure what profiling_value in the presented snippet, so I started from the object structure in OP

var desiredResult = jsonObj.custom.services.reduce(function(result, service){
  result[service.name] = jsonObj.custom.fields.filter(function(field){
       return field.services.indexOf(service.name) >= 0;
   }).map(function(field){ return field.name; });
  return result;
}, {});

这给出了提到的对象的预期结果.

This gives the expected result for mentioned object.

reduce需要迭代所有服务并将结果累加到一个对象中.然后,对于每个服务字段,仅将包含链接到该服务的字段迭代为filter.最后,已过滤字段的列表被转换为字符串列表(map)(它们的名称),并插入累加器

reduce is required to iterate over all services and accumulate result in one object. Then for each service fields are iterated to filter out only those that contain link to this service. And finally list of filtered fields is transformed (map) into list of strings - their names - and inserted into accumulator

这篇关于在JSON中使用动态多维键/值对的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆