简体   繁体   中英

How to change an objects key values to lowerCase for sorting

I am creating a custom sorting method in Angular that takes as a parameter a name of type string. In the.html file, whenever a user clicks on the arrows lets say for example next to 'UserName', the UserName is passed in as an argument to my sorting method. I want my method to be case-insensitive and can't seem to figure out a way to access and change the array of objects key values. Using the above example of 'UserName', I want to access the objects key name 'UserName', and make the value lower case before sorting. That way my sorting method will work properly. Keep in mind, my data is inside an array that contains objects of user info. I am using bracket notation also to keep it dynamic; for example in my method you will see a[name] < b[name] where [name] is equal to whatever the user clicks on.

My.TS FILE

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

You can see in my.ts file I am trying to find out a way to change the objects key value.

.HTML file

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

You can make it slightly more organized like this:

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

Just add toLowerCase() modifier. if a[name] could be something not string, then a[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;
  });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM