Объединить итоговые данные JSON - PullRequest
0 голосов
/ 19 сентября 2018

У меня есть образец Stackblitz.com здесь https://stackblitz.com/edit/angular-xhulyo?file=app%2Fapp.component.ts,, и мне нужно объединить общее количество пользователей, таких как dbrown или qadmin, вместо того, чтобы отображать их в отдельных строках.В настоящее время он отображает результаты, подобные следующим:

User    Success Failure
dbrown  16  0
qadmin  4   0
dbrown  4   1
qadmin  21  2
administrator   42  0
cooper  8   0
ad.brown    7   0

, а итоговые значения dbrown должны быть 20 и 1, а qadmin - 25 и 2. Из кода видно, что он просто перебирает переменную users.Вот app.component.ts:

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular 5';
  users: any[] = [];
  items: any;

  ngOnInit() {
    this.items = {"Users":{"InteractiveLogon":[{"UserName":"dbrown","Success":"16","Failed":"0"},{"UserName":"qadmin","Success":"4","Failed":"0"}],"NetworkLogon":[{"UserName":"dbrown","Success":"4","Failed":"1"},{"UserName":"qadmin","Success":"21","Failed":"2"},{"UserName":"administrator","Success":"42","Failed":"0"},{"UserName":"cooper","Success":"8","Failed":"0"},{"UserName":"ad.brown","Success":"7","Failed":"0"}]}};

    for (let user of this.items.Users.InteractiveLogon)
      this.users.push(user);

    for (let user of this.items.Users.NetworkLogon)
      this.users.push(user);
  }

}

А вот app.component.html:

<hello name="{{ name }}"></hello>
<p>
  Start editing to see some magic happen :)
</p>
<hr>
<table *ngIf="users">
  <thead>
    <tr>
      <th align=left>User</th>
      <th>Success</th>
      <th>Failure</th>
    </tr>
  </thead>
    <tr *ngFor="let row of users" >
      <td style="padding-right: 15px">{{row.UserName}}</td>
      <td>{{row.Success}}</td>
      <td>{{row.Failed}}</td>
    </tr>
</table>

Я обнаружил проблемы, такие как Объединение наборов данных JSON и Сумма свойств объекта в массиве , которые говорят об использовании свойств, таких как hasOwnProperty и map, и сокращают функции, но я не уверен, как их использовать для объединения итогов отдельных пар значений с одинаковым именем икак сложить только эти.

РЕДАКТИРОВАТЬ:

Я пошел с комбинацией вкладчиков, чтобы сделать это более ясным (для меня).Комментарии приветствуются, если это не лучший способ сделать это.Я тоже избавился от этого оператора.Новый StackBlitz здесь .Функция combUserTotals выглядит следующим образом:

combineUserTotals() {
  let result: any, results: any[] = [];

  this.users.map((user) => {
    result = results.find(u => u.UserName == user.UserName);

    if (!result)
      results.push({ UserName: user.UserName, Success: Number(user.Success), Failed: Number(user.Failed) });
    else {
      result.Success += Number(user.Success);
      result.Failed += Number(user.Failed);
    }
  });

  return results;
}

Ответы [ 3 ]

0 голосов
/ 19 сентября 2018

Вы можете видеть, есть ли пользователь в массиве пользователей, если нет, нажмите его, иначе добавьте значения к существующему.Поскольку ваши значения являются строками, пришлось преобразовать их с помощью parseIt (), чтобы они суммировали.

for (let user of this.items.Users.InteractiveLogon) {
  let _user = this.users.find( u => u.UserName == user.UserName );
  if ( _user ){
    _user.Success = parseInt(_user.Success) + parseInt(user.Success);
    _user.Failed = parseInt(_user.Failed) + parseInt(user.Failed);
  }
  else {
    this.users.push(user);
  }
}
for (let user of this.items.Users.NetworkLogon) {
  let _user = this.users.find( u => u.UserName == user.UserName );
  if ( _user ){
    _user.Success = parseInt(_user.Success) + parseInt(user.Success);
    _user.Failed = parseInt(_user.Failed) + parseInt(user.Failed);
  }
  else {
    this.users.push(user);
  }
}

RESULT

User    Success Failure
dbrown  20  1
qadmin  25  2
administrator   42  0
cooper  8   0
ad.brown    7   0
0 голосов
/ 19 сентября 2018

Итак, вот как классные ребята в Javascript делают вещи:

Таким образом, избыточность - очень полезный способ обработки массива без использования forloops.Я понимаю, что вы не знаете, как работает Reduce, но посмотрите на следующие ссылки:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce https://www.w3schools.com/jsref/jsref_reduce.asp

 this.users= [...this.items.Users.NetworkLogon,...this.items.Users.InteractiveLogon];

https://stackblitz.com/edit/angular-jspxb9

Теперь, чтобы добавить дубликаты:

 let result = [];
 this.users.map((a)=> {
    if (!this[a.UserName]) {
        this[a.UserName] = { UserName: a.UserName, Success: 0, Failed: 0 };
        result.push(this[a.UserName]);
    }
    this[a.UserName].Success += Number(a.Success);
    this[a.UserName].Failed += Number(a.Failed);
}, Object.create(null));
this.users = result;

enter image description here

0 голосов
/ 19 сентября 2018

Вы можете добавить своих пользователей по имени пользователя на карту:

const map = {};
for (let user of this.items.Users.InteractiveLogon)
  if (!map[user.UserName]) {
     map[user.UserName] = user;
  } else {
     map[user.UserName].Success += user.Success;
     map[user.UserName].Failed += user.Failed;
  }
}
for (let user of this.items.Users.NetworkLogon)
  if (!map[user.UserName]) {
     map[user.UserName] = user;
  } else {
     map[user.UserName].Success += user.Success;
     map[user.UserName].Failed += user.Failed;
  }
}

Затем снова добавить свои элементы в список

for (let key in map) {
  if (map.hasOwnProperty(key)) {
     this.users.push(map[key]);
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...