创建包含缺少对象的数组

时间:2016-02-06 14:59:37

标签: javascript algorithm

我有一个对象数组。每个gateType:entry都需要跟gateType:exit个对象。

问题是某些条目对象和一些退出对象丢失/跳过。我需要创建一个包含缺少对象的对象数组。

            [{
                "dateTime": "2016-01-28 15:18:26",
                "gateType": "entry",
            }, {
                "dateTime": "2016-01-28 15:18:27",
                "gateType": "exit",
            }, {
                "dateTime": "2016-01-28 15:19:26",
                "gateType": "entry",
            }, {
                "dateTime": "2016-01-28 15:19:27",
                "gateType": "exit",
            }, {
                "dateTime": "2016-01-28 15:20:26",
                "gateType": "entry",
            },
// here is the exit object is missing for above
            {
                "dateTime": "2016-01-28 15:21:25",
                "gateType": "entry",
            }, {
                "dateTime": "2016-01-28 15:21:26",
                "gateType": "exit",
            }, {
                "dateTime": "2016-01-28 15:22:25",
                "gateType": "entry", 
            }, {
                "dateTime": "2016-01-28 15:22:26",
                "gateType": "exit",
            }, 
// here is the entry object is missing for below
            {
                "dateTime": "2016-01-28 15:23:26",
                "gateType": "exit",
            }]

每个entry都需要跟exit。但是你可以看到一些入口或出口对象不存在。

以上示例的解决方案是:

            [{
                "dateTime": "2016-01-28 15:20:26",
                "gateType": "exit",
            },{
                "dateTime": "2016-01-28 15:23:26",
                "gateType": "enty",
            }]

我的解决方案是这样的,但它并没有像我期望的那样工作:

function detectMissingOnes(rows) {

        var missings = [];
        var current = null;

        rows.forEach(function (key, index) {


            if (index == 0) {

                if(key.gateType == "exit"){


                    var resultDate = moment(key.dateTime);
                    resultDate = resultDate.subtract(1, 'seconds').format("YYYY-MM-DD HH:mm:ss");

                    missings.push({
                        dateTime: resultDate,
                        gateNumber: key.gateNumber,
                        gateType: "entry",
                        personId: key.personId,
                        fix: 1
                    });

                }

                current = key;
                return true;
            }

            if (current.gateType == key.gateType) {

                var type = key.gateType == "entry" ? "exit" : "entry";

                var resultDate = moment(current.dateTime);
                if(type == "entry"){
                    resultDate = resultDate.subtract(1, 'seconds').format("YYYY-MM-DD HH:mm:ss");
                }else {
                    resultDate = resultDate.add(1, 'seconds').format("YYYY-MM-DD HH:mm:ss");
                }


                missings.push({
                    dateTime: resultDate,
                    gateNumber: current.gateNumber,
                    gateType: type,
                    personId: current.personId,
                    fix: 1
                });

            }

            current = key;

        });

        return missings;
    }

你能不能用或不用lodash来编写算法?

2 个答案:

答案 0 :(得分:1)

试试这个:

ref.child('messages_per_user').child('user1').on('value', function(snapshot) {
    snapshot.forEach(function(messageSnapshot) {
        ref.child('notifications').child(messageSnapshot.key).once('value', function(notificationSnapshot) {
            console.log(notificationSnapshot.val());
        })
    });
});

答案 1 :(得分:1)

以下是返回缺失记录的代码。在你的问题中,你没有提到在缺失的记录中添加/减去第二个,但是在你的代码中它存在,所以我做了同样的事情。

我没有使用任何库,所以即使是使用标准JavaScript函数完成秒的操作,也会使它更长一些。

此实时片段允许您输入输入数组(JSON),并获取函数的结果(也是JSON)。



// main algorithm:
function detectMissingOnes(rows) {
    var collect = rows.reduce(function (collect, curr) {
        var expectedMove = collect.openEntry ? "exit" : "entry";
        var expectedPerson = collect.openEntry ? collect.openEntry.personId : curr.personId;
        console.log('expected move: ', expectedMove, ' person: ', expectedPerson);
        console.log('current move: ', curr.gateType, ' person:', curr.personId);
        if (expectedMove == curr.gateType && 
                expectedPerson == curr.personId) {
            console.log('ok');
            // OK, we have the expected gate type and personID.
            // If this is an entry, keep track of it, otherwise clear tracks
            collect.openEntry = collect.openEntry ? null : curr; // toggle
        } else {
            console.log('mismatch');
            // not OK, add to orphans list
            if (collect.openEntry)       collect.orphans.push(collect.openEntry);
            if (curr.gateType == 'exit') collect.orphans.push(curr);
            // If this is an entry, replace previous track
            collect.openEntry = curr.gateType == 'entry' ? curr : null;
        }
        return collect;
    }, {orphans: [], openEntry: null}); // initial value of collect
    
    // if last one was an "entry", add it to the orphans list
    if (collect.openEntry) {
        collect.orphans.push(collect.openEntry);
    }
    
    // for all orphans: return the missing counter part.
    return collect.orphans.map(function(orphan) {
        var mydate = new Date(orphan.dateTime.replace(/^(.{10}) (.{8})$/, '$1T$2Z'))
        // add/subtract one second:
        mydate = new Date(+mydate + 1000*(orphan.gateType == "entry" ? 1 : -1));
        return {
            id:         orphan.id,
            dateTime:   mydate.toISOString().replace(/^(.{10})T(.{8}).*$/, '$1 $2'),
            gateNumber: orphan.gateNumber,
            gateType:   orphan.gateType == "entry" ? "exit" : "entry",
            personId:   orphan.personId,
            fix:        orphan.fix
        };
    });
}

// default input data:
var data = [
  {
    "id": 517,
    "dateTime": "2016-01-29 13:17:46",
    "gateNumber": "192.168.1.206",
    "gateType": "exit",
    "personId": 1,
    "fix": 0
  },
  {
    "id": 568,
    "dateTime": "2016-01-29 14:03:44",
    "gateNumber": "192.168.1.203",
    "gateType": "entry",
    "personId": 1,
    "fix": 0
  },
  {
    "id": 675,
    "dateTime": "2016-01-29 14:10:07",
    "gateNumber": "192.168.1.203",
    "gateType": "entry",
    "personId": 1,
    "fix": 0
  },
  {
    "id": 108,
    "dateTime": "2016-01-29 14:11:51",
    "gateNumber": "192.168.1.205",
    "gateType": "entry",
    "personId": 1,
    "fix": 0
  },
  {
    "id": 170,
    "dateTime": "2016-01-28 14:27:58",
    "gateNumber": "192.168.1.206",
    "gateType": "exit",
    "personId": 2,
    "fix": 0
  },
  {
    "id": 66,
    "dateTime": "2016-01-28 14:33:07",
    "gateNumber": "192.168.1.200",
    "gateType": "exit",
    "personId": 2,
    "fix": 0
  },
  {
    "id": 395,
    "dateTime": "2016-01-28 16:26:04",
    "gateNumber": "192.168.1.206",
    "gateType": "exit",
    "personId": 2,
    "fix": 0
  }
];
// Get input controls:
var input = document.getElementById('input');
var output = document.getElementById('output');
var button = document.getElementById('button');

// default input value:
input.value = JSON.stringify(data, null, 2);

// execute process on button click:
button.onclick = function () {
    var data = JSON.parse(input.value);
    var missing = detectMissingOnes(data);
    output.textContent = JSON.stringify(missing, null, 2);
}

div { bottom: 0; right: 0; left: 0; top: 0; position: absolute }
table { with: 100%; height: 100% }
tr.page { with: 100%; height: 100% }
td { vertical-align: top; width: 50%}
textarea { min-width: 320px; width: 100%; height:100% }

<div class="big"><table border=1>
    <tr><th>Enter input (JSON):<button id="button">Process</button></th>
        <th>Output</th></tr>
    <tr class="page"><td><textarea id="input"></textarea></td>
        <td><pre id="output"></pre></td></tr>
</table></div>
&#13;
&#13;
&#13;

该函数不会改变传递的参数(数组)。返回的数组仅列出缺少的对象。请注意,如果对象中有其他属性,则需要调整代码。