1

I have an array of objects with an "asymetric" structure where keys are not the same and there are some nested object. I need loop through this:

  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"
    }]

what i need is to return a structure like this

first row = my name 5 10

second row = my second name 15 25

I tried a for in a custom Pipe...

    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;
      }
    }

but id doesn't work...

can someone help?

2
  • The key name is always there, but the date as you guess could change... so i can't know the name of the date keys Commented Apr 16, 2018 at 19:42
  • Such a poor design: anyway, if you capture the keys (regardless of value) with Object.keys() then you have something you can iterate over. If the structure stays the same you can use the key index to gather the value and the next key to get the second value, and the third key (name) to get the name. Commented Apr 16, 2018 at 19:45

2 Answers 2

1

I'd recommend avoid using a Pipe for this type of advanced data manipulation and instead just generate the necessary data structure for display/usage in something like ngOnInit() or prior to binding to a public variable. You can use Object.keys() in combination with Array.prototype.map(), Array.prototype.join() and ternary statements to generate the data rows.

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>

Here is an example in action.

Hopefully that helps!

Sign up to request clarification or add additional context in comments.

1 Comment

If value is 0 it will be replaced with '' as it's falsy :)
0

An option is to reduce each object's keys to an array, then just join if you want each item to be a string:

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(' ')
    );

1 Comment

thanks dude, i would rather prefere the alex approach. you're great

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.