Как изменить значения ключа объекта на нижний регистр для сортировки

#javascript #angular

#javascript #angular

Вопрос:

Я создаю пользовательский метод сортировки в Angular, который принимает в качестве параметра имя типа string . В файле .html всякий раз, когда пользователь нажимает на стрелки, скажем, например, рядом с «UserName», имя пользователя передается в качестве аргумента моему методу сортировки. Я хочу, чтобы мой метод не учитывал регистр и, похоже, не может найти способ доступа и изменения массива значений ключей объектов. Используя приведенный выше пример «UserName», я хочу получить доступ к имени ключа объекта «UserName» и сделать значение строчным перед сортировкой. Таким образом, мой метод сортировки будет работать правильно. Имейте в виду, что мои данные находятся внутри массива, который содержит объекты пользовательской информации. Я также использую обозначение в скобках, чтобы сохранить его динамичным; например, в моем методе вы увидите [name] <b[name], где [name] равно тому, на что нажимает пользователь.

Мой ФАЙЛ .TS

 @Component({
  selector: 'app-users',
  templateUrl: './users.component.html',
  styleUrls: ['./users.component.scss']
})
export class UsersComponent extends ComponentCanDeactivate implements OnDestroy {
  entries: User[] = []; isAscendingOrder=false; isFaSort=true; sortByParam='';
  faEdit=faEdit; faTrash=faTrash; faCaretSquareDown=faCaretSquareDown; faCaretSquareUp=faCaretSquareUp; faSort=faSort;
  @ViewChild('addUserForm') formValues;

  constructor(private userService: UserService, private globals: GlobalsService, private modalService: NgbModal) {
    super(); this.load();
  }

  ngOnDestroy() { try { this.modalService.dismissAll(); } catch(err) { console.log(err); } }

  canDeactivate(): boolean { return !this.modalService.hasOpenModals();}

  load(){
    this.userService.getAllUsers(r => {
      if (r) {
        this.entries = r; this.getValues(this.entries)
      } else {
        this.globals.toastr.error('Error getting users');
      }
    });
  }



  switchIcon() {
    if(this.isFaSort) {
      return faSort;
    } else {
      return this.isAscendingOrder? faCaretSquareUp:faCaretSquareDown;
    }
  }

  getValues(userArray: User[]) {
    userArray.forEach(e=> {
      const result = Object.entries(e).map(([k,v]) => {
        e.UserName = v.toLowerCase();
      })
      console.log(result);
    });

  }

  sortByField(name:string) {

    this.isFaSort = false;
    if(this.sortByParam == name) {
      this.isAscendingOrder= !this.isAscendingOrder;
    } else {
      this.sortByParam = name;
      this.isAscendingOrder = true;
    }




    if(this.isAscendingOrder) {
        return this.entries.sort((a, b) => {
        if (a[name] < b[name])
          return -1;
        if (a[name] > b[name])
          return 1;
        return 0;
        });
      } else {
      return this.entries.sort((a, b) => {
        if (a[name] < b[name])
          return 1;
        if (a[name] > b[name])
          return -1;
        return 0;
      });
    }
  }
 

Вы можете видеть в моем файле .ts, что я пытаюсь найти способ изменить значение ключа объекта.

.HTML-файл

 <div class="table-overflow-container">
                <table class='table table-bordered table-fixed-header table-striped table-narrow table-hover'>
                    <thead class="my-thead">
                        <tr>
                            <td class="clickable" (click)="sortByField('UserName')">User name<fa-icon style="float: right;"  [icon]="switchIcon()">
                            </fa-icon>
                            </td>
                            <td class="clickable" (click)="sortByField('Email')">Email<fa-icon style="float: right;"  [icon]="switchIcon()">
                            </fa-icon></td>
                            <td>Roles</td>
                            <td class="clickable">Disabled<fa-icon style="float: right;"  [icon]="switchIcon()">
                            </fa-icon></td>
                        </tr>
                    </thead>
                    <tbody>
                        <tr *ngFor="let u of entries">
                            <td class="clickable" (click)="editUser(u.id)">{{u.UserName}}</td>
                            <td class="clickable" (click)="editUser(u.id)">{{u.Email}}</td>
                            <td class="clickable" (click)="editUser(u.id)">{{ getRoleNames(u.UserRoles) }}</td>
                            <td class="clickable" (click)="editUser(u.id)">{{u.Disabled==0?"No":"Yes"}}</td>
                        </tr>
                    </tbody>
                </table>
 

Ответ №1:

Вы можете сделать его немного более организованным, например, так:

 sortByField(name:string) {

    this.isFaSort = false;
    if(this.sortByParam == name) {
      this.isAscendingOrder= !this.isAscendingOrder;
    } else {
      this.sortByParam = name;
      this.isAscendingOrder = true;
    }

    function getLowerCaseEntry(a, b) {
        return a[b].toLowerCase();
    }

    function compareStr(a ,b, asc) {
        return asc ? a.localeCompare(b) : b.localeCompare(a);
    }

    this.entries.sort((x,y) => compareStr(getLowerCaseEntry(x, name), getLowerCaseEntry(y, name), this.isAscendingOrder));
}
 

Ответ №2:

Просто добавьте модификатор toLowerCase() . если [name] может быть чем-то не строковым, то [name].toString().toLowerCase()

 if(this.isAscendingOrder) {
    return this.entries.sort((a, b) => {
    if (a[name].toLowerCase() < b[name].toLowerCase())
      return -1;
    if (a[name].toLowerCase() > b[name].toLowerCase())
      return 1;
    return 0;
    });
  } else {
  return this.entries.sort((a, b) => {
    if (a[name].toLowerCase() < b[name].toLowerCase())
      return 1;
    if (a[name].toLowerCase() > b[name].toLowerCase())
      return -1;
    return 0;
  });
}
 

Комментарии:

1. вау.. Я был почти уверен, что добавлял метод toLowerCase, и он постоянно говорил мне, что не может .. но, черт возьми, теперь это работает! Это то, что я искал, основываясь на моем коде, поэтому будет принятым ответом, хотя мне нравится подход, предложенный выше, чтобы лучше организовать мой код.