Несколько для петель внутри друг друга - PullRequest
0 голосов
/ 12 ноября 2018

Я столкнулся с проблемой, которая действительно беспокоит меня.Я пытался гуглить проблему, но без удачи.Я получил следующий код, где я хочу применить определенные узлы к DOM, получая информацию из массива.Цикл while работает отлично, но когда дело доходит до цикла «for», все становится просто прикольно.Я хочу отфильтровать разные биты, используя "collection_id" из массива "bitValues" и идентификаторы "collectionValues".Информация, которую следует применить, выглядит следующим образом:

    var bitValues = [{
                    'id': 1,
                    'collection_id': 1,
                    'description': "Amazing description",
                    'radio': "ANR",
                    'date': "01-01-2018",
                    'time': "11:45:00",
                    'seconds': 10,
                    'delta': '8.5',
                    'gain_loss': '2',
                    'total_listeners': '13.343',
                    'delta_listeners': '22.340',
                }, {
                    'id': 2,
                    'collection_id': 2,
                    'description': "DR P3 music is amazing",
                    'radio': "DR P3",
                    'date': "05-01-2018",
                    'time': "13:45:00",
                    'seconds': 16,
                    'delta': '12',
                    'gain_loss': '82',
                    'total_listeners': '15.343',
                    'delta_listeners': '102.340',
                },
                {
                    'id': 3,
                    'collection_id': 2,
                    'description': "Let's go!",
                    'radio': "Nova FM",
                    'date': "25-01-2018",
                    'time': "23:45:00",
                    'seconds': 126,
                    'delta': '53',
                    'gain_loss': '17',
                    'total_listeners': '28.343',
                    'delta_listeners': '22.340',
                }
            ];

let collectionValues = [{
                'id': 1,
                'demographic': "All females",
                'delta': "19.5",
                'gain_loss': "62.126",
                'total_listeners': '43.343',
                'delta_listeners': '22.340',
                bits: bitValues
            }, {
                'id': 2,
                'demographic': "All 12-24",
                'delta': "10.5",
                'gain_loss': "52.126",
                'total_listeners': '153.343',
                'delta_listeners': '132.340',
                bits: bitValues
            }];

jQuery для применения данных выглядит следующим образом:

    while (i < collectionAmount) {
        (Code that works)...

        for (let n = 0; n < bitAmount; n++) {

           collection_id = collectionValues[i].id;
           bit_reference_id = bitValues[n].collection_id;

           if(collection_id == bit_reference_id) {
       $('.freestyle-deltas_details_bits').append(`
<tr>
                                                            <td><span 
    class="font-weight-bold">Bit
                                                                        ${bitValues[n].id}: </span>(
                                                                        ${bitValues[n].time}, ${bitValues[n].seconds} sec)</td>
                                                                    <td><span class="colorChangeByValueDelta">${bitValues[n].delta}%</span></td>
                                                                    <td><span class="colorChangeByValueGainLoss">${bitValues[n].gain_loss}%</span></td>
                                                                    <td>${bitValues[n].total_listeners}</td>
                                                                    <td>${bitValues[n].delta_listeners}</td>
                                                            </tr>
                                                        `);
                                                        }
                                                    };
    i++;
    }

Может кто-нибудь помочь с этой проблемой?Спасибо!

Ответы [ 3 ]

0 голосов
/ 12 ноября 2018
 let table = document.createElement("table");//creating a table element
 $(table).append("<tr></tr>");// inserting a row element in the table
 let head = table.getElementsByTagName("tr")[0];// selecting the row elment previously selected
 for(key in bitValues[0]){//looping through all keys in the object
     $(head).append(`<th>${key}</th>`);// putting each key as a head in the first row of the table
 }
 $(table).append("<tbody></tbody>")// creating a table body
 for(row of bitValues){// looping through each object in bitValues array
      let tr = document.createElement("tr");// creating a row for each object in the array
      for(x in row){// looping through each key of an object in the array
         $(tr).append(`<td>${row[x]}<td>`);// putting the value of each key in a td tag and appending it to tr
      }
      table.appendChild(tr);// appending the tr to the table
 }
 $('.freestyle-deltas_details_bits').append(table);

Надеюсь, это поможет

0 голосов
/ 12 ноября 2018

Хотя я не знаю, что такое collectionAmount, я бы предположил, что это просто количество элементов в collectionValues.

То, что вы хотите - это способ визуализации только этих элементов изbitValues, у которого collection_id соответствует id коллекции, над которой в данный момент выполняется работа, верно?В этом случае используйте filter и reduce.Поскольку вы можете потерять filter, добавив простой if-else внутри reduce, просто используйте reduce.

Прежде всего, давайте немного очистим и переместим шаблон в его собственную функцию:

  /* template */
  const bitValueTemplate = data => `<tr>
    <td>
      <span class="font-weight-bold">Bit ${data.id}:</span>
      (${data.time}, ${data.seconds} sec)
    </td>
    <td>
      <span class="colorChangeByValueDelta">${data.delta}%</span>
    </td>
    <td>
      <span class="colorChangeByValueGainLoss">${data.gain_loss}%</span>
    </td>
    <td>${data.total_listeners}</td>
    <td>${data.delta_listeners}</td>
  </tr>`;

Теперь перейдем к хитрому моменту, который соберет полную строку HTML из списка bitValues за раз (то есть содержит несколько элементов <tr>):

  /* renders a list into a simple string, only adds items where a certain
  property has a certain value. uses a template function/render function to
  render each item, then adds it to the end of the overall string. returns
  the complete string when finished */
  const renderByPropWith = (prop, value, renderFn, xs) => {
    return xs.reduce((html, x) => {
      if (x[prop] === value) {
        return html + renderFn(x);
      }
      return html;
    }, '');
  }

ОК, время попробовать:

  var collectionAmount = collectionValues.length;
  var i = 0;
  while (i < collectionAmount) {
    // (Code that works)...


    var html = renderByPropWith('collection_id', collectionValues[i].id, bitValueTemplate, bitValues);
    $('.freestyle-deltas_details_bits').append(html);

    i++;
  }
0 голосов
/ 12 ноября 2018

Отличное время для использования двойной фильтрации!Вот почему я люблю Javascript.

const result = first.filter (firstId => second.filter (secondId => firstId.id === secondId.id))

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

Если вы используете bitValues ​​в качестве первого массива, вы получите список, содержащий объекты в bitValuesкоторые соответствуют в collectionValues.

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