遍历对象搜索 属性 并在成功时修改原始对象

Loop Through Object Searching For Property And Modify Original Object on Success

var myObj = 
    data: {
    {
    chairId: "CHAIRCHROME009",    
    relatedOrders: [
        {
            someProp: 45423234,
            data : {
                firstOrder: {},
                relatedOrders: [
                    {
                        someProp: 5757587,
                        data : {
                            firstOrder: {},
                            relatedOrders: [ ],
                            notifications: [
                                {
                                    notificationId: "CHAIR-0909FF",
                                    latestNotification: {                                
                                        latestNotificationAction: "New",
                                        priority: "High",                                
                                    }
                                }
                            ],
                            relations: [ ]
                        }
                    }
                ],
                relations: [ ]
            }
        }
    ],
    relations: [ ]
}
}

我如何无休止地循环遍历包含数组和对象的对象,本质上是搜索 notifications 属性.

在上面的示例中,通知是 myObj 的 2 级深度,但它可以是 1 级或 100 级。 notifications 将始终在 relatedOrders 下找到我然后需要确定 notifications.latestNotification.latestNotificationAction

的值

如果未找到通知,应返回 nullfalse

我试过:

function isThereRelatedOrders(myObj) {
    for(var k in myObj) {
        var v = myObj[k];

        if (k === "relatedOrders") {                
            isThereData(v[0]);
        }
    }
}

function isThereData(relatedOrder) {
    for(var y in relatedOrder) {
        var t = relatedOrder[y];

        if (y === "data") {                
            isThereNotification(t);
        }
    }
}

function isThereNotification(t) {
    for(var x in t) {            
        var j = t[x];

        if (x === "notifications") {
            console.lig('notifications found');
            if(j[0].latestNotification.latestNotificationAction  === "New") {                
                console.log('is new alert');
                // Add a property to my original myObj root level of alert: new
            }
            else {                
                console.log('is old alert');
                // Add a property to my original myObj root level of alert: old
            }
        }
        else if(x === "relatedOrders") {
            alert('SUB relatedOrders found');
            isThereRelatedOrders(j[0]);
        }
        else {
            alert('no notifications found');
        }
    }
}

isThereRelatedOrders(myObj);

有了上面的内容,一旦我的代码必须第二次调用 isThereRelatedOrders(),它就不会遇到 if 语句。我想它的原因是现在需要查找 .data??

执行完上述操作后,我希望返回这样的内容:

var myObj = {
    chairId: "CHAIRCHROME009",
    alert: "New"
    ////////

这是我的尝试,使用您的数据,但已清理为有效...单击 "Run code snippet" 按钮以 运行 它。

var myObj = {
  data: {
    chairId: "CHAIRCHROME009",
    relatedOrders: [{
      someProp: 45423234,
      data: {
        firstOrder: {},
        relatedOrders: [{
          someProp: 5757587,
          data: {
            firstOrder: {},
            relatedOrders: [],
            notifications: [{
              notificationId: "CHAIR-0909FF",
              latestNotification: {
                latestNotificationAction: "New",
                priority: "High",
              }
            }],
            relations: []
          }
        }],
        relations: []
      }
    }],
    relations: []
  }
};

function findAllNotifications(obj, chairId) {
  var result = [];
  Object.keys(obj).forEach(function(prop) {
    if (prop === 'chairId') {
      chairId = obj.chairId;
    }
    if (prop === 'notifications') {
      obj.notifications.forEach(function(notif) {
        result.push({
          chairId: chairId,
          alert: notif.latestNotification.latestNotificationAction
        });
      });
    }
    switch (typeof obj[prop]) {
      case 'object':
        result = result.concat(findAllNotifications(obj[prop], chairId));
        break;
      case 'array':
        obj[prop].forEach(function(sub) {
          result = result.concat(findAllNotifications(sub, chairId));
        });
        break;
    }
  });
  return result;
}

var result = findAllNotifications(myObj);
console.log("Result:", result);

// Doing this so you can see the result on the web page...
document.body.appendChild(document.createTextNode(JSON.stringify(result)));

// To "reassign" to the original object:
// myObj= findAllNotifications(myObj);

此提案使用迭代和递归方法来获取想要的 属性 notifications 及其内容。如果找到,则将内容推入 result 数组。如果什么都找不到,则数组保持为空。

function iter(o) {
    if (Array.isArray(o)) {
        o.forEach(iter);
        return;
    }
    if (typeof o === 'object') {
        Object.keys(o).forEach(function (k) {
            if (k === 'chairId') {
                chairId = o[k];
            }
            if (k === 'notifications') {
                o[k].forEach(function (a) {
                    if ('latestNotificationAction' in a.latestNotification) {
                        result.push({
                            chairId: chairId,
                            alert: a.latestNotification.latestNotificationAction
                        });
                    }
                });
            }
            iter(o[k]);
        });
    }
}

var myObj = { data: { chairId: "CHAIRCHROME009", relatedOrders: [{ someProp: 45423234, data: { firstOrder: {}, relatedOrders: [{ someProp: 5757587, data: { firstOrder: {}, relatedOrders: [], notifications: [{ notificationId: "CHAIR-0909FF", latestNotification: { latestNotificationAction: "New", priority: "High", } }], relations: [] } }], relations: [] } }], relations: [] } },
    chairId,
    result = [];

iter(myObj);
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

编辑:

一个考虑 datarelatedOrders 属性之间切换的解决方案。

function iter(o, flip) {
    if (Array.isArray(o)) {
        o.forEach(function (a) {
            iter(a, flip);
        });
        return;
    }
    if (typeof o === 'object') {
        if ('chairId' in o) {
            chairId = o.chairId;
        }
        if (
            flip === 'relatedOrders' &&
            'notifications' in o &&
            0 in o.notifications &&
            'latestNotification' in o.notifications[0] &&
            'latestNotificationAction' in o.notifications[0].latestNotification
        ) {
            result.push({
                chairId: chairId,
                alert: o.notifications[0].latestNotification.latestNotificationAction
            });
            return;
        }
        flip in o && iter(o[flip], flipFlop[flip]);
    }
}

var myObj = { data: { chairId: "CHAIRCHROME009", relatedOrders: [{ someProp: 45423234, data: { firstOrder: {}, relatedOrders: [{ someProp: 5757587, data: { firstOrder: {}, relatedOrders: [], notifications: [{ notificationId: "CHAIR-0909FF", latestNotification: { latestNotificationAction: "New", priority: "High", } }], relations: [] } }], relations: [] } }], relations: [] } },
    chairId,
    result = [],
    flipFlop = { relatedOrders: 'data', data: 'relatedOrders' };

iter(myObj, 'data');
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

JSONPath 非常适合此类任务。它非常灵活,而且很有趣。
你可以在这里下载一个实际的叉子:https://github.com/s3u/JSONPath

1。简单的任务,简单的解决方案:

如果您的数据中只有一把椅子,您可以轻松获取 chairId 并让 JSONPath 完成其余工作:

var result = {
    chairId: myObj.data.chairId,
    alert: JSONPath({json: myObj, wrap: false, path: '$..latestNotificationAction'}) || false
};
var resultString = JSON.stringify(result, 0, 4);
document.write('<pre>' + resultString + '</pre>');
<script src="https://raw.githack.com/s3u/JSONPath/master/lib/jsonpath.js"></script>
<script>
var myObj = {
    data: {
        chairId: "CHAIRCHROME009",
        relatedOrders: [{
            someProp: 45423234,
            data: {
                firstOrder: {},
                relatedOrders: [{
                    someProp: 5757587,
                    data: {
                        firstOrder: {},
                        relatedOrders: [],
                        notifications: [{
                            notificationId: "CHAIR-0909FF",
                            latestNotification: {
                                latestNotificationAction: "New",
                                priority: "High",
                            }
                        }],
                        relations: []
                    }
                }],
                relations: []
            }
        }],
        relations: []
    }
};
</script>

2。复杂的任务,简单的解决方案:

如果你的数据比较复杂,你可以使用回调函数,每次找到带有 latestNotification 的椅子时都会调用该函数:

function find(obj, foundCallBack) {

  JSONPath({
      json: obj, resultType: 'parent', wrap: false, 
      path: '$..chairId', 
      callback: function(chair) {
          JSONPath({
              json: chair, resultType: 'parent', wrap: false, 
              path: '$..latestNotification', 
              callback: function(notification) {foundCallBack({
                  chairId: chair.chairId,
                  alert: notification.latestNotification.latestNotificationAction,
                  priority: notification.latestNotification.priority
              })}});
      }});
}
find(myObj, function(result){
   var resultString = JSON.stringify(result, 0, 4);
   alert(resultString);
   document.write('<pre>' + resultString + '</pre>');
});
<script src="https://raw.githack.com/s3u/JSONPath/master/lib/jsonpath.js"></script>
<script>
var myObj = {
    data: {
        employees: [1, 2, 3, 4],
        chairs: [
            {
                chairId: "CHAIRCHROME009",
                relatedOrders: [{
                    someProp: 45423234,
                    data: {
                        firstOrder: {},
                        relatedOrders: [{
                            someProp: 5757587,
                            data: {
                                firstOrder: {},
                                relatedOrders: [],
                                notifications: [{
                                    notificationId: "CHAIR-0909FF",
                                    latestNotification: {
                                        latestNotificationAction: "New1",
                                        priority: "High",
                                    }
                                },
                                    {
                                        notificationId: "CHAIR-0909FF",
                                        latestNotification: {
                                            latestNotificationAction: "New2",
                                            priority: "Medium",
                                        }
                                    }],
                                relations: []
                            }
                        }],
                        relations: []
                    }
                }],
                relations: []
            },
            {
                chairId: "CHAIRCHROME0077",
                relatedOrders: [{
                    someProp: 45423234,
                    data: {
                        firstOrder: {},
                        relatedOrders: [{
                            someProp: 5757587,
                            data: {
                                firstOrder: {},
                                relatedOrders: [],
                                notifications: [{
                                    notificationId: "CHAIR-090922FF",
                                    latestNotification: {
                                        latestNotificationAction: "New3",
                                        priority: "Low",
                                    }
                                }],
                                relations: []
                            }
                        }],
                        relations: []
                    }
                }],
                relations: []
            }
        ]
    }
};
</script>