Удаление объектов из массива глубоко вложенных объектов по значению свойства - PullRequest
0 голосов
/ 10 июля 2020

Считайте, что у меня есть массив вложенных объектов. Одним из возможных примеров сценария может быть:

content: [
    {
        prop1: someValue,
        prop2: someValue,
        content: [
            {
                prop2: someValue,
                prop3: someValue,
                myProperty: myValue
            },
            {
                prop1: someValue,
                prop3: someValue,
                myProperty: otherValue
            }
        ]
    },
    {
        prop5: someValue,
        prop2: someValue
    }
]

Вот возможности:

  • Структура начинается с content[], но потомки могут иметь или не иметь свойство content.
  • Уровень иерархии может быть любым.
  • Свойства, содержащиеся в объектах, не всегда одинаковы, т.е. один объект может иметь свойства x, y, z, а другой может иметь v, w, z свойства.
  • Если какой-либо объект в иерархии имеет ключ myProperty, ключа content не будет.
  • Более одного объекта в иерархии могут иметь myProperty со значением 'myValue.

Мое требование:

  • Если на каком-либо уровне объект имеет свойство myProperty со значением myValue, удалите весь объект (НЕ ПРОСТО СВОЙСТВО) из иерархии.

Моя попытка на данный момент:

  private removeObjects(content: any, values: string[]): any {
    if (!content || content.length === 0) {
      return
    }
    content = content.filter((c) => {
      if (!c.myProperty) return true
      return c.myProperty.indexOf(values) > 0
    })
    // Here is my problem since I am supposed to do a recursive call on each of child contents,
    // how do I merge back the original array?
    return this.removeObjects(content, values)
  }

Ответы [ 4 ]

1 голос
/ 10 июля 2020

Следующее рекурсивно возвращает новый массив без изменения исходного

const content = [{
    prop1: "someValue",
    prop2: "someValue",
    content: [{
        prop2: "someValue",
        prop3: "someValue",
        myProperty: "myValue"
      },
      {
        prop1: "someValue",
        prop3: "someValue",
        myProperty: "otherValue"
      }
    ]
  },
  {
    prop5: "someValue",
    prop2: "someValue"
  }
]

function removeObjects(content) {
  return content.reduce((arr, obj) => {
    if (obj["myProperty"] && obj["myProperty"] === "myValue") {
      return arr
    } else if (obj["content"] && obj["content"].length) {
      arr.push({ ...obj,
        content: removeObjects(obj["content"])
      })
      return arr
    } else {
      arr.push(obj);
      return arr;
    }
  }, []);
}



console.log(removeObjects(content))

Ожидаемый результат:

const content = [{
        prop1: "someValue",
        prop2: "someValue",
        content: [
          {
            prop1: "someValue",
            prop3: "someValue",
            myProperty: "otherValue"
          }
        ]
      },
      {
        prop5: "someValue",
        prop2: "someValue"
      }
    ]
0 голосов
/ 10 июля 2020

Используйте рекурсивный подход, чтобы иметь filter массив элементов и их content массив.

const filter = (arr, name, value) =>
  arr
    .filter((obj) => !(name in obj && obj[name] === value))
    .map((obj) => {
      const nObj = { ...obj };
      if (obj.content && Array.isArray(obj.content)) {
        nObj.content = filter(obj.content, name, value);
      }
      return nObj;
    });
    
content = [
  {
    prop1: 'someValue',
    prop2: 'someValue',
    content: [
      {
        prop2: 'someValue',
        prop3: 'someValue',
        myProperty: 'myValue',
      },
      {
        prop1: 'someValue',
        prop3: 'someValue',
        myProperty: 'otherValue',
      },
    ],
  },
  {
    prop5: 'someValue',
    prop2: 'someValue',
  },
];



const updated = filter(content, "myProperty", "myValue");

console.log(updated);
0 голосов
/ 10 июля 2020

Вы можете использовать функцию ниже, чтобы получить ожидаемый результат:

let data = {
    content: [
        {
            prop1: 'someValue',
            prop2: 'someValue',
            content: [
                {
                    prop2: 'someValue',
                    prop3: 'someValue',
                    myProperty: 'myValue'
                },
                {
                    prop1: 'someValue',
                    prop3: 'someValue',
                    myProperty: 'otherValue'
                }
            ]
        },
        {
            prop5: 'someValue',
            prop2: 'someValue'
        }
    ]
}

function removeMyvalyeObj(data) {
    for (let i = data.content.length - 1; i >= 0; i--) {
        if (data.content[i].myProperty === 'myValue') {
            data.content.splice(i, 1);
        } else if(data.content[i].content) {
            removeMyvalyeObj(data.content[i])
        }
    }
}

removeMyvalyeObj(data);
console.log(data);
0 голосов
/ 10 июля 2020

Попробуйте это, (это JavaScript версия)

    let someValue = 'a';
    let otherValue ='x';
    let myValue = 'xy';
    let content = [
        {
            prop1: someValue,
            prop2: someValue,
            content: [
                {
                    prop2: someValue,
                    prop3: someValue,
                    myProperty: myValue
                },
                {
                    prop1: someValue,
                    prop3: someValue,
                    myProperty: otherValue
                }
            ]
        },
        {
            prop5: someValue,
            prop2: someValue
        }
    ];


     function removeObjects(content, values) {
         debugger;
        if (!content || content.length === 0) {
          return
        }
        content = content.filter((c) => {
          if (!c.myProperty) return true
           return c.myProperty.indexOf(values) > 0
        })
        // Here is my problem since I am supposed to do a recursive call on each of child contents,
        // how do I merge back the original array?
        return content.map(x => ({
            ...x,
            content: removeObjects(x.content, values)
        }))
      }

      console.log(removeObjects(content, 'x'))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...