*ngFor Angular через вложенный массив с разными ключами и уровнем

У меня есть массив объектов с асимметричной структурой, где ключи не совпадают и есть какой-то вложенный объект. Мне нужен цикл через это:

  obj = [{
      "d14042018": {
        "date": "14-04-2018",
        "value": 5
      },
      "d02042018": {
        "date": "02-04-2018",
        "value": 10
      },
      "name": "my name"
    },
    {
      "d14042018": {
        "date": "14-04-2018",
        "value": 15
      },
      "d02042018": {
        "date": "02-04-2018",
        "value": 25
      },
      "name": "my second name"
    }]

мне нужно вернуть такую ​​структуру

первая строка = мое имя 5 10

вторая строка = мое второе имя 15 25

Я попробовал for в пользовательской трубе...

    import { Pipe, PipeTransform } from '@angular/core';
    @Pipe({
      name: 'keys'
    })
    export class KeysPipe implements PipeTransform {

      transform(value: any, args?: any): any {
        let keys: string;

        if (value) {
          for (var prop in value) {
      
            if(typeof value[prop] != 'object') {
               keys = value[prop];
            } else {
              for (var subprop in prop) {
                keys = prop.subprop;
              }
            }
          }
        }
        return keys;
      }
    }

но id не работает...

может кто-нибудь помочь?


person Gael Sapori    schedule 16.04.2018    source источник
comment
Имя ключа всегда есть, но дата, как вы догадываетесь, может измениться... поэтому я не могу знать имя ключей даты.   -  person Gael Sapori    schedule 16.04.2018
comment
Такой плохой дизайн: в любом случае, если вы захватываете ключи (независимо от значения) с помощью Object.keys(), тогда у вас есть что-то, что вы можете перебрать. Если структура остается прежней, вы можете использовать индекс ключа, чтобы собрать value, и следующий ключ, чтобы получить второе значение, и третий ключ (имя), чтобы получить имя.   -  person Randy Casburn    schedule 16.04.2018


Ответы (2)


Я бы рекомендовал избегать использования Pipe для этого типа расширенной обработки данных и вместо этого просто создавать необходимую структуру данных для отображения/использования в чем-то вроде ngOnInit() или до привязки к общедоступной переменной. Вы можете использовать Object.keys() в сочетании с Array.prototype.map(), Array.prototype.join() и троичными операторами для создания строк данных.

TypeScript:

this.rows = Object.keys(obj).map(key => {
  const o = this.data[key];
  const { name } = o;
  const values = Object.keys(o)
                   .map(k => o[k]['value'])
                   .join(' ');

  return { name, values };
});

HTML:

<ul>
  <li *ngFor="let row of rows">{{row.name}} {{row.values}}</li>
</ul>

Вот пример в действии.

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

person Alexander Staroselsky    schedule 16.04.2018
comment
Если значение равно 0, оно будет заменено на '', так как оно ложно :) - person funkizer; 16.04.2018

Вариант состоит в том, чтобы уменьшить ключи каждого объекта до массива, а затем просто присоединиться, если вы хотите, чтобы каждый элемент был строкой:

const obj = [...]; // your example array
const flattened = obj.map(
    o => Object.keys(o).reduce(
        (acc,cur) => cur === 'name' 
            ? [o[cur], ...acc] // key is 'name', push value to first
            : [...acc, o[cur].value] // other than name, push value of value last
        , []).join(' ')
    );
person funkizer    schedule 16.04.2018
comment
спасибо, чувак, я бы предпочел подход Алекса. Ты замечательный - person Gael Sapori; 16.04.2018