0

I have following multi dimensional object array:

var data ='{
    "Form": [],
    "Report": [],
    "Misc": [],
    "Test5": [],
    "Test4": [],
    "Provider": [
        { "Memorial Hospital": ["img0.jpg"] },
        { "Cooper Memorial Hospital": [
            "img1.jpg",
            { "Emergency Reports": ["img2.jpg"] },
            { "Diagnostic Reports": [
                "img3.jpg",
                {
                    "12/12/2006": ["img4.jpg", "img5.jpg"],
                    "03/13/2009": ["img6.jpg", "img7.jpg"]
                }
            ]},
            { "Accident Reports": ["img8.jpg"] },
            { "Other Reports": ["img9.jpg", "img10.jpg"] }
        ]}
    ]
}';

I want to remove data from the array its img7.jpg under "03/13/2009"

What I do is:

var obj = JSON.parse(data);
console.log(obj['Provider'][1]["Cooper Memorial Hospital"][2]["Diagnostic reports"][0]["12/12/2006"]).splice(0,1);

That is all working, now issue arises when I add/remove arrays from "Cooper Memorial Hospital". Index gets recounted.

So I want to splice with out index, is there any way I can remove the img from the arrays and sub arrays just calling by img3.jpg:

removeImg("img3.jpg", obj['Provider']);

Something like this.

Update: I tried with this code, but it requires some additional code for looping through the sub arrays:

function remove(arr, what) {
    var found = arr.indexOf(what);
    while (found !== -1) {
       arr.splice(found, 1);
        found = arr.indexOf(what);
        if(found)
        break;
    }
}

remove(a,"img1");
websterz
  • 35
  • 1
  • 8
  • "That is all working,".... Doubt that... There should be a null or undefined error with that line – epascarello Sep 06 '16 at 12:08
  • 1
    Why is the data structured that way? Those arrays with mixed types of contents are just asking for problems. – Cerbrus Sep 06 '16 at 12:09
  • I guess you shouldn't delete with splice but replace the items that you would like to remove with a `null` so that the indices wouldn't change/shift. – Redu Sep 06 '16 at 12:10
  • What data structure do you suggest for the same working ? @Cerbrus – websterz Sep 06 '16 at 12:21
  • Depends on what _exactly_ you want to achieve with the data. – Cerbrus Sep 06 '16 at 12:22
  • `removeImg()` needs to be recursive so it can drill into the nested arrays and objects. – Barmar Sep 06 '16 at 12:23
  • SO is not a free coding service. You need to make an attempt to solve this yourself. If you can't get it working, post your code and we'll help you fix it. – Barmar Sep 06 '16 at 12:25
  • Yes i tried this it works but for delete/modify operations. However when i add new data like in Cooper Memorial Hospital i add more images it changes all index of following objects. @Redu – websterz Sep 06 '16 at 12:26
  • I am not asking for the coding service, i just need directions :) @barmar furthermore i already posted the code that i use to remove and add data into arrays. However the issue is dynamically index generations on each update of arrays. – websterz Sep 06 '16 at 12:28
  • Don't put code in comments, edit the question – Barmar Sep 06 '16 at 12:29
  • @websterz Loop through the array with `for()`, and if it matches the thing you're looking for splice it out. But you have to loop backwards. – Barmar Sep 06 '16 at 12:30
  • @websterz when you need to add an item, add the it to the end of the array so that the existing items keep their index as it is. When you need to delete replace the item with null. – Redu Sep 06 '16 at 12:31
  • @websterz See http://stackoverflow.com/questions/3954438/remove-item-from-array-by-value/21289314#21289314 for how to remove an item from an array by value. – Barmar Sep 06 '16 at 12:32
  • I updated the post, with a function to remove, can you check and provide the directions. @Barmar – websterz Sep 06 '16 at 12:33
  • That will work for a 1-dimensional array. You need to recurse into the nested objects for your structure. – Barmar Sep 06 '16 at 12:35
  • Thank you @Barmar let me implement it. – websterz Sep 06 '16 at 12:35
  • @Redu yes that is correct, but i need to add in middle and in start aswell. – websterz Sep 06 '16 at 12:36
  • @websterz Someone already posted an answer for you. – Barmar Sep 06 '16 at 12:37

1 Answers1

0

My first instinct is to try and fix this server side, because the data-format looks a bit weirdly nested.

To fix it client side, you'll need to write a recursive function that checks all nested arrays for the string and deletes it on the go.

First, the code to remove an item from an array:

 var removeStringFromArray = function(str, array) {
  var index = array.indexOf(str);
  if (index !== -1) {
    array.splice(index, 1);
  }
};

This dynamically looks up the index of the string and splices it. Note that this mutates your array.

To look through all items in an object, we'll use this snippet:

Object.keys(obj).forEach(function(key) {
  var value = obj[key];
  // Do something with value...
});

This gets an array of keys and loops its values. If these two snippets look okay to you, you can combine them in a recursive function like I did in the example below. I haven't optimized for performance or lines of code; I tried to make it readable. Also note that I'm using Array.isArray and a quick-and-dirty isPrimitive check.

var removeStringFromArray = function(str, array) {
  var index = array.indexOf(str);
  if (index !== -1) {
    array.splice(index, 1);
  }
};

var removeStringFromArraysInVariable = function(str, val) {
    if (isPrimitive(val)) {
      // Don't do anything for falsy, bools, strings, numbers
      return;
    }
    
    // For an array
    if (Array.isArray(val)) {
      // Remove all strings first
      removeStringFromArray(str, val); 
      
      // Call method recursively for any non string values that might be there
      val.forEach(function(innerVal) {
       removeStringFromArraysInVariable(str, innerVal);
      });
      return;
    }
    
    // If we get here, it's probably an object
    Object.keys(val).forEach(function(key) {
      // Call recursively for each property value
      removeStringFromArraysInVariable(str, val[key]);
    });
};

// You might want to look up if this is a fool proof way to check for primitives
var isPrimitive = function(val) {
  if (!val) return true;
  
  var constr = (val).constructor;
  return (
    constr === Number ||
    constr === Boolean ||
    constr === String);
}  


// Test data
var data = {
  "Form": [],
  "Report": [],
  "Misc": [],
  "Test5": [],
  "Test4": [],
  "Provider": [{
    "Memorial Hospital": ["img0.jpg"]
  }, {
    "Cooper Memorial Hospital": [
      "img1.jpg", {
        "Emergency Reports": ["img2.jpg"]
      }, {
        "Diagnostic Reports": [
          "img3.jpg", {
            "12/12/2006": ["img4.jpg", "img5.jpg"],
            "03/13/2009": ["img6.jpg", "img7.jpg"]
          }
        ]
      }, {
        "Accident Reports": ["img8.jpg"]
      }, {
        "Other Reports": ["img9.jpg", "img10.jpg"]
      }
    ]
  }]
};

removeStringFromArraysInVariable("img3.jpg", data);
console.log(data);
user3297291
  • 19,011
  • 1
  • 24
  • 39