简体   繁体   中英

Javascript equivalent of Perl hash table comparisons

I am relatively new to Javascript and have a need to do something that is easy for me to code up in Perl, but I cannot quite figure out the Javascript equivalent. Two arrays were populated with the contents of text windows named baseText and newText, where each window has very simple lines like A = 1, B = 5, etc.:-

function myJSComparator() {
    var baseEntries = stringAsLines(byId("baseText").value);
    var baseAllAppOptions = [];
    for (var i = 0; i < baseEntries.length; i++) {
        var fields = baseEntries[i].split("=");
        var baseAppOption = {optionName:fields[0],optionValue:fields[1]};
        baseAllAppOptions.push(baseAppOption);
    }
    var newEntries = stringAsLines(byId("newText").value);
    var newAllAppOptions = [];
    for (var i = 0; i < newEntries.length; i++) {
        var fields = newEntries[i].split("=");
        var newAppOption = {optionName:fields[0],optionValue:fields[1]};
        newAllAppOptions.push(newAppOption);
    }
}

How do I iterate over baseAllAppOptions and newAllAppOptions and output the following:-

1) A summary of only the optionName.fields that are the same in both baseAllAppOptions and newAllAppOptions, but whose corresponding optionValue.fields are different.

2) A summary of only the optionName.fields (and their corresponding optionValue.fields) that are in baseAllAppOptions, but not in newAllAppOptions.

3) A summary of only the optionName.fields (and their corresponding optionValue.fields) that are in the newAllAppOptions, but not in baseAllAppOptions.

I have three text windows waiting to receive the outputs of each line above. I plan to print to each text window like so...

    for (var i = 0; i < baseEntries.length; i++) {
        document.getElementById("baseChangeText").value += baseAllAppOptions[i].optionName + baseAllAppOptions[i].optionValue + String.fromCharCode(13);
    }

The above is just an example of how I would iterate over the array entries and print them out without doing any direct comparisons. But I need the format to be what is described in the document.getElementById line.

Any general guidance that can be shared would be much appreciated!

BTW, here is what I am working with:-

https://jsfiddle.net/e4bunLvh/57/

In each "Release #* App Option Defaults" window, just add something like A = 1 to both and then B = 2 in one and C = 3 in another.

Thanks!

If you convert each set of options to an object (equivalent to a hash in Perl), then it should be a simple matter of looping through the keys (and using Object.keys makes this simple) and simply testing for a difference in value, or defined-ness.

Example:

 var getObjectWithContents = function(elementId) { return document.getElementById(elementId) .value .trim() .replace('\\r\\n', '\\n') // replace Windows linebreaks to Unix .replace('\\n\\n', '\\n') // replace double-linebreaks to single .split('\\n').map(function(line) { // map into single key-value pairs var value = line.split('='); var key = value[0].trim(); var val = value[1].trim(); var o = {}; o[key] = val; return o; }).reduce(function(o, p) { // reduce array of single key-value pairs to one object var key = Object.keys(p).shift(); var val = p[key]; o[key] = val; return o; }, {}); }; var getDifferenceByValue = function(optionsBase, optionsNew) { var difference = []; Object.keys(optionsBase).forEach(function(key) { var baseValue = optionsBase[key]; // var newValue = optionsNew[key]; if (newValue !== undefined && baseValue !== newValue) { difference.push(key); } }); return difference; }; var getDifferenceByOption = function(a, b) { var difference = {}; Object.keys(a).forEach(function(key) { if (b[key] === undefined) { difference[key] = a[key]; } }); return difference; }; var outputToTextarea = function outputToTextarea(area, o, type) { var text = document.getElementById(area); text.value = Object.keys(o).map(function(key) { return key + '=' + o[key]; }).join('\\n'); }; var outputDiffByValue = function outputDiffByValue(array) { var text = document.getElementById('outputByValue'); text.value = array.join('\\n'); }; var getDiff = function getDiff() { var app1Defaults = getObjectWithContents('baseText'); var app2Defaults = getObjectWithContents('newText'); var stuffInBothWithDifferentValues = getDifferenceByValue(app1Defaults, app2Defaults); var stuffInBaseAndNotInNew = getDifferenceByOption(app1Defaults, app2Defaults); var stuffInNewAndNotInBase = getDifferenceByOption(app2Defaults, app1Defaults); outputDiffByValue(stuffInBothWithDifferentValues); outputToTextarea('diffBase', stuffInBaseAndNotInNew); outputToTextarea('diffNew', stuffInNewAndNotInBase); // console.log({ // stuffInBothWithDifferentValues, // stuffInBaseAndNotInNew, // stuffInNewAndNotInBase, // }); }; window.addEventListener('load', function() { var button = document.getElementById('logDiff'); button.addEventListener('click', function(e) { getDiff(); e.preventDefault(); return false; }, false); }, false); 
 <div> <textarea class="textbox" id="baseText" rows="5"> a = 1 b = 2 c = 2 f = 5 </textarea> <textarea class="textbox" id="newText" rows="5"> a = 0 b = 1 d = 3 e = 4 </textarea> <button id="logDiff">Get Differences</button> </div> <div> <h3><label for="outputByValue">Differences by Value</label></h3> <textarea class="textbox" id="outputByValue" rows="5"></textarea> </div> <div> <h3><label for="diffBase">Stuff in Base (but not in New)</label></h3> <textarea class="textbox" id="diffBase" rows="5"></textarea> </div> <div> <h3><label for="diffNew">Stuff in New (but not in Base)</label></h3> <textarea class="textbox" id="diffNew" rows="5"></textarea> </div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM