1

this seems quite an easy task, but for some reason am stuck! I tried several solutions I found in SE, mainly to recursively iterate the array/object, such as How to iterate over an array and remove elements in JavaScript and Looping through array and removing items, without breaking for loop (and many others) but with no luck!

I have this array

{
  "condition": "AND",
  "rules": [
    {
      "id": "loc1",
      "type": "string",
      "input": "text",
      "operator": "equal",
      "value": "test0"
    },
    {
      "id": "sessionIgnore",
      "type": "string",
      "input": "text",
      "operator": "equal",
      "value": "ignore0"
    },
    {
      "condition": "AND",
      "rules": [
        {
          "id": "loc1",
          "type": "string",
          "input": "text",
          "operator": "equal",
          "value": "test1"
        },
        {
          "id": "sessionIgnore",
          "type": "string",
          "input": "text",
          "operator": "equal",
          "value": "ignore1"
        },
        {
          "condition": "AND",
          "rules": [
            {
              "id": "loc1",
              "type": "string",
              "input": "text",
              "operator": "equal",
              "value": "test2"
            },
            {
              "id": "sessionIgnore",
              "type": "string",
              "input": "text",
              "operator": "equal",
              "value": "ignore2"
            }
          ]
        }
      ]
    },
    {
      "condition": "AND",
      "rules": [
        {
          "id": "loc1",
          "type": "string",
          "input": "text",
          "operator": "equal",
          "value": "test3"
        },
        {
          "id": "sessionIgnore",
          "type": "string",
          "input": "text",
          "operator": "equal",
          "value": "ignore3"
        }
      ]
    }
  ],
  "valid": true
}

and i want to remove all sessionIgnore elements

{
  "condition": "AND",
  "rules": [
    {
      "id": "loc1",
      "type": "string",
      "input": "text",
      "operator": "equal",
      "value": "test0"
    },
    {
      "condition": "AND",
      "rules": [
        {
          "id": "loc1",
          "type": "string",
          "input": "text",
          "operator": "equal",
          "value": "test1"
        },
        {
          "condition": "AND",
          "rules": [
            {
              "id": "loc1",
              "type": "string",
              "input": "text",
              "operator": "equal",
              "value": "test2"
            }
          ]
        }
      ]
    },
    {
      "condition": "AND",
      "rules": [
        {
          "id": "loc1",
          "type": "string",
          "input": "text",
          "operator": "equal",
          "value": "test3"
        }
      ]
    }
  ],
  "valid": true
}

what seems to be the problem in my case: in both cases, I go through the array recursively

  • the delete x/array.slice() approach: seems to keep the references to an empty array element, which I then have to call a cleanup method and I would prefer to avoid this
  • I created an arrayRemove() function that removes the x element from the given array, but in this case, I seem to have a logic issue, and I can't parse anything after the second level of the array

any help is appreciated!

Edit: in case a rules object has only a sessionIgnore element in it, I want the whole section removed i.e. referencing the above array, if the sessionIgnore with value ignore2 was the only object in its 'rules' group, I want the whole section removed edit2: added the expected result

edit in regards with nina's conversation:

in case the object is like this:

{
      "condition": "AND",
      "rules": [
        {
          "id": "loc1",
          "type": "string",
          "input": "text",
          "operator": "equal",
          "value": "test1"
        },
        {
          "id": "sessionIgnore",
          "type": "string",
          "input": "text",
          "operator": "equal",
          "value": "ignore1"
        },
        {
          "condition": "AND",
          "rules": [
            {
              "id": "sessionIgnore",
              "type": "string",
              "input": "text",
              "operator": "equal",
              "value": "ignore2"
            }
          ]
        }
      ]
    }

i want this

{
      "condition": "AND",
      "rules": [
        {
          "id": "loc1",
          "type": "string",
          "input": "text",
          "operator": "equal",
          "value": "test1"
        }
      ]
    }
hahaha
  • 1,001
  • 1
  • 16
  • 32
  • 1
    That's not an array - this is an object. – VLAZ May 17 '19 at 11:51
  • do you want the same object, or a new object with changed data? – Nina Scholz May 17 '19 at 11:53
  • 1
    @VLAZ But the property `"rules"` is an array. I guess the OP is referring to this property, not the entire object. – Pedro Corso May 17 '19 at 11:53
  • @PedroCorso yes! exactly – hahaha May 17 '19 at 11:54
  • @NinaScholz i dont mind as long as I have an array without the sessionIgnore values :D – hahaha May 17 '19 at 11:54
  • @PedroCorso yet "I have this array" shows an object. Since this is VERY frequently confused term, I cannot be sure if OP means "I have the array in this object" or "I have this object which I call an array" – VLAZ May 17 '19 at 11:55
  • @vlaz yes i agree that might not be clear, but the end request is very clear :) – hahaha May 17 '19 at 11:56
  • @Alexandros put your expected output in question. you are bit confused about termobject array property – Mannan Bahelim May 17 '19 at 12:00
  • @MannanBahelim added the expected result – hahaha May 17 '19 at 12:02
  • @Alexandros yet your terminology isn't. I don't really know why you want to keep insisting in being unclear but in programming we do prefer terminology to be applied correctly. Especially considering people might come here after a google search. If somebody tries "filter array" and gets here the answers are not likely to help them out if they have plain old `[1, 2, 3, 4]` – VLAZ May 17 '19 at 12:02

1 Answers1

1

You could filter rules by checking id an if rules exists, filter this property, too.

function remove(o) {
    if (o.id === "sessionIgnore") return false;
    if (o.rules) o.rules = o.rules.filter(remove);
    return true;
}

var data = { condition: "AND", rules: [{ id: "loc1", type: "string", input: "text", operator: "equal", value: "test0" }, { id: "sessionIgnore", type: "string", input: "text", operator: "equal", value: "ignore0" }, { condition: "AND", rules: [{ id: "loc1", type: "string", input: "text", operator: "equal", value: "test1" }, { id: "sessionIgnore", type: "string", input: "text", operator: "equal", value: "ignore1" }, { condition: "AND", rules: [{ id: "loc1", type: "string", input: "text", operator: "equal", value: "test2" }, { id: "sessionIgnore", type: "string", input: "text", operator: "equal", value: "ignore2" }] }] }, { condition: "AND", rules: [{ id: "loc1", type: "string", input: "text", operator: "equal", value: "test3" }, { id: "sessionIgnore", type: "string", input: "text", operator: "equal", value: "ignore3" }] }], valid: true };

remove(data);

console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • very close to the end result! and much simpler than any of my tries but in case of my first edit: if a rule has only a sessionIgnore element in it, i want the entire parent element removed – hahaha May 17 '19 at 12:08
  • i don't get you which part should be removed? actually my result looks like your result ... – Nina Scholz May 17 '19 at 12:17
  • it does :D I didnt append another array because the question is already huge, in case the element that holds ignore2 and test2, only has ignore2, i want the whole parent element removed, instead of an element with `"condition": "AND", "rules": []`, in other words, remove the element with value test2 and run your solution to that dataset :) – hahaha May 17 '19 at 12:19
  • then you need to create a (small) data set for your use case, add it to the question along with the wanted outcome. – Nina Scholz May 17 '19 at 12:20
  • it makes no sense, because the first example returns nothing because every nested `id: 'sessionIgnore'` leads to a removen of the higher level. basically you can get only the result from the first example or only the one of the send example, but not both. – Nina Scholz May 17 '19 at 12:47