уродливые вложенные для каждого в javascript лучшие практики - PullRequest
0 голосов
/ 30 сентября 2018

Привет, мой код выглядит очень хакерским, я мог бы сделать то же самое с forloop, что было бы лучше для производительности, но это будет выглядеть еще ужаснее.Есть ли более чистый / лучший способ сделать это?

это моя модель данных

this.data = [
  {
    title: 'Math',
    img: this.mathImage,
    children: [
      {
        title: 'Calculus I & II',
        open: false,
        children: [
          {
            title: 'Differentials',
            open: false,
            children: [
              {
                title: 'Integration by parts',
                key: 'Differentials1',
                mainsub: 'Math',
                middlesub: 'Calculus I & II',
                lowsub: 'Differentials',
                saved: true // <--------------- HERE IS THE PROPERTY
              },
              {
                title: 'Integration by parts',
                key: 'Differentials2',
                mainsub: 'Math',
                middlesub: 'Calculus I & II',
                lowsub: 'Differentials',
                saved: true,
              },
            ]
          }
        ]
      }
    ]
  }
]

это мой код, который устанавливает свойство 'сохраненное' в false

removeFromFavoritesinSubjects(item) {
  this.data.forEach(list => {
    if (list.title === item.mainsub) {
      list.children.forEach(subitem => {
        if (subitem.title === item.middlesub) {
          subitem.children.forEach(items => {
            if (items.title === item.lowsub) {
              items.children.forEach(i => {
                if (i.key === item.key) {
                  i.saved = false;
                }
              })
            }
          })
        }
      })
    }
  })
} 

Ответы [ 3 ]

0 голосов
/ 01 октября 2018

Я собираюсь предположить, что вы хотите изменить сохраненное значение на ложное, когда вы находитесь на самом низком уровне (т. Е. На других уровнях нет сохраненных свойств).

В этом ответе используется для ... из для рекурсивного обхода массивов.

function changeSaved(data, key, value) {

  // loop through every object in the array
  for(var element in data){

    // see if there is a children node
    if(element.children){

      // run this function recursively on the children array
      changeSaved(element.children);

    } else {

      // no children key, set the value
      element[key] = value;
    }

  }

}

Вы бы назвали это так:

changeSaved(data, 'saved', 'false');
0 голосов
/ 01 октября 2018

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

// flattenArray helper function turns nested array into flat array
function flattenArray (array) {
  return array.reduce((result, item) =>
    result.concat([ item ], flattenArray(item.children || []))
  , []);
}

// later in code
{
  // ...
  removeFromFavoritesInSubjects ({ key }) {
    // Consider all children are alongside with each other
    // [..., { title: 'Calculus I & II', ... }, { title: 'Differentials', ... }, ...]
    flattenArray(this.data).forEach(item => {
      if (item.key === key) {
        item.saved = false;
      }
    });
  }
  // ...
}

Также не беспокойтесь слишком сильноо производительности для использования for..loop против forEach.

0 голосов
/ 01 октября 2018

Линейный поиск в структуре данных очень неэффективен, если вам приходится делать это чаще, вы должны либо сохранить прямую ссылку на объект в item, либо использовать структуру данных, которая обеспечивает эффективный поиск по ключу (например, Map).

Вместо вложенных циклов (это было бы лучше при for … of, чем .forEach()), я бы использовал цепочечные .find() вызовы, хотя:

removeFromFavoritesinSubjects(item) {
  const list = this.data.find(list => list.title === item.mainsub);
  if (!list) return;
  const subitem = list.children.find(subitem => subitem.title === item.middlesub);
  if (!subitem) return;
  const items = subitem.children.find(items => items.title === item.lowsub);
  if (!items) return;
  const i = items.children.find(i => i.key === item.key);
  if (!i) return;
  i.saved = false;
}

(при условии, что в массиве нет дубликатов, и каждый вызов removeFromFavouritesInSubjects() устанавливает не более одного свойства .saved).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...