Issue with merging and reordering two arrays of objects

34 views Asked by At

I'm trying to figure out how to merge two arrays of objects. Here's what I need to do:

  • field property is the unique identifier of each object
  • Output needs to only have the objects listed in the originalArray, including objects in originalArray that do not exist in localStorageArray
  • Order of localStorageArray needs to be maintained, with attention paid to previous requirement (order should be: bar, bee, foo, baz)
  • Output needs to contain the following property values from localStorageArray: hidden and width (field is a give-in, since its the identifier)
  • All other properties of originalArray need to be maintained in output

Here's my wack at it:

var outputArray = [];

localStorageArray.forEach(function(localItem){
    originalArray.forEach(function(originalItem){
        if(originalItem.field === localItem.field){
            var item = JSON.parse(JSON.stringify(originalItem));
            item.hidden = localItem.hidden;
            item.width = localItem.width;
            outputArray.push(item);
        }
    });
});

Full JS Fiddle

I was able to get the ordering correct and the properties right, but one issue I'm having is when a object exists in originalArray that doesn't exist in localStorageArray, that object is not included in the outputArray.

Any suggestions to my solution?

Here are my arrays:

var originalArray = [
    {field: "foo", hidden: true, sortable: false, template: "<div>#=text#</div>", width: "20px", propA: "a", propB: "b"},
    {field: "bee", hidden: true, sortable: false, template: "=#text#", int: 4},
    {field: "bar", hidden: false, sortable: false, template: "", width: "20%", propC: "C"},
    {field: "baz", hidden: false, sortable: true, template: "<span>#=text#</span>", int: 3}
];

var localStorageArray = [
    {field: "bar", hidden: false, sortable: false, width: "100px"},
    {field: "foo", hidden: true, sortable: false, template: "<div>#=text#</div>", width: "40px"},
    {field: "boo", hidden: true, sortable: true, template: "<div>Boo: #=text#</div>", width: "200px"},
    {field: "baz", hidden: true, template: "baz:#=text#", width: "20px"}
];

And here is my desired output:

var desiredArray =  [
   {field: "bar", hidden: false, sortable: false, template: "", width: "100px", propC: "C"},
   {field: "bee", hidden: true, sortable: false, template: "=#text#", int: 4},
   {field: "foo", hidden: true, sortable: false, template: "<div>#=text#</div>", width: "40px", propA: "a", propB: "b"},
   {field: "baz", hidden: true, sortable: true, template: "<span>#=text#</span>", width: "20px", int: 3}
]
1

There are 1 answers

1
Ana F On

If I understand correctly, you want to overwrite the hidden and width properties of those objects in originalArray that are also present in localStorageArray (2 objects are considered the same if field property is the same)

    (function () {
    var fieldArray = localStorageArray.map(function(e) { return e.field; });
    originalArray.forEach(function(originalItem) {
      var index = fieldArray.indexOf(originalItem.field);
      var localItem; 
      if(index !== -1) {
        //it's also in localStorage, overwrite 
        localItem = localStorageArray[index];
        originalItem.hidden = localItem.hidden || originalItem.hidden;
        originalItem.width = localItem.width || originalItem.width;
        outputArray.push(originalItem);
      }
    })();

Instead of creating an additional array, you can also loop through localStorageArray and compare the field property