2
\$\begingroup\$

I'm trying to return a list of objects called orders based on a string search that the user enters. orders has a title and a description. The function loops through the orders object and tries to find matches between the search string and order titles or descriptions. The search should be able to find matches even if there are words in the string we are comparing to, and then sort the results by how many matches are found for each order.

import { EditOrderComponent } from './edit-order/edit-order.component';
import { DeleteOrderComponent } from './delete-order/delete-order.component';
import { MatDialog } from '@angular/material';
import { YearService } from './../year.service';
import { CreateOrderService } from '../order.service';
import { Component, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { Order } from '../order.model';
import { ActivatedRoute } from '@angular/router';
import { AdminService } from '../admin.service';

@Component({
  selector: 'app-view',
  templateUrl: './view.component.html',
  styleUrls: ['./view.component.css']
})
export class ViewComponent implements OnInit {
  orders: Order[] = [];
  private orderSub: Subscription;
  currentYear: number | string;
  urlYear: any;
  isAdmin: boolean;
  isAdminCreate: boolean;
  myModel = true;
  order = 'DESC';
  titles = 'titleDESC';
  pub = 'pubDESC';
  enteredSearch = '';
  misMatchSearch = '';
  searching = false;
  orderCount = 0;

  constructor(public adminService: AdminService, public orderService: CreateOrderService, public yearsService: YearService,
    private route: ActivatedRoute, public dialog: MatDialog) {}

  ngOnInit() {
    this.yearsService.cast$.subscribe(current => (this.currentYear = current));

    this.adminService.isAdminLogin();
    this.adminService.cast$.subscribe(admin => {
      (this.isAdmin = admin)
    });
    this.adminService.caseSOA$.subscribe(create => {
           (
      this.isAdminCreate = create
    )
  });

    this.orderService.getOrders('All Years');
    this.orderSub = this.orderService
      .getOrdersUpdatedListener()
      .subscribe((orders: Order[]) => {
        this.orders = orders;
        this.orderCount = this.orders.length;
      });
  }

  isOrdersAvailable(): Boolean {
  if ( this.orderCount > 0) {
      return true;
    }
    return false;
  }

  resetSearch() {
    this.orderService.getOrders('All Years');
    this.orderSub = this.orderService
      .getOrdersUpdatedListener()
      .subscribe((orders: Order[]) => {
        this.orders = orders;
        this.orderCount = this.orders.length;
      });
    this.enteredSearch = null;
    this.searching = false;
  }

  // order {
  // title: string,
  // descrtion: string,
  // ...
  // }
  onSearch() {
    if ( this.enteredSearch && this.enteredSearch.length > 0) {
      this.orderService.getOrders('All Years');
      this.orderSub = this.orderService
        .getOrdersUpdatedListener()
        .subscribe((orders: Order[]) => {
          this.orders = orders;
          this.orders = this.searchOrders(this.enteredSearch, this.orders);
          if ( this.orders ) {
          this.orderCount = this.orders.length;
          }
          if ( this.orderCount === 0) {
            this.setUnfoundSearch();
          }
        });
        this.searching = true;
    }
  }

  setUnfoundSearch() {
    this.misMatchSearch = this.enteredSearch;
  }

  searchOrders(search: string, orders: Order[]): Order[] {
    if ( search ) {
    search = search.trim();
    // Array passed by reference.
    const tempOrders = [...orders];
    const unsortedOrders = this.searchDriver(search, tempOrders);
    const orderToReturn = this.sortResults(unsortedOrders);

    return orderToReturn;
    }
  }

  // Builds string[]s to compare and compares.
  searchDriver(search: string, orders: Order[]): any[] {
    const tempOrders = [...orders];
    const ascOrders = [];
    const searchArray = this.splitString(search);
    for (let i = 0; i < tempOrders.length; i++) {
      // Combine the title and desctiption into one long string[].
      const compare = [];
      let tempArray = this.splitString(tempOrders[i].title);
      for (let j = 0; j < tempArray.length; j++) {
        compare.push(tempArray[j]);
      }
      tempArray = this.splitString(tempOrders[i].description);
      for (let k = 0; k < tempArray.length; k++) {
        compare.push(tempArray[k]);
      }
      compare.push(tempOrders[i].orderID);
      const amountSame = this.arrayCompare(searchArray, compare);
      // If more than one match is found add it to the array.
      if (amountSame >= 1) {
        const anOrder = tempOrders[i];
        const feed = { amountSame, anOrder };
        ascOrders.push(feed);
      }
    }
    return ascOrders;
  }

  // Break down strings into individual words to compare.
  splitString(stringToSplit: string): string[] {
    const string = stringToSplit;
    let stringArray = [];
    stringArray = string.split(' ');
    return stringArray;
  }

  // compare two arrays search and title/desc values
  arrayCompare(searchArray: string[], compareToArray: string[]): number {
    let counter = 0;
    for (let searchIndex = 0; searchIndex < searchArray.length; searchIndex++) {
      for (let compareToIndex = 0; compareToIndex < compareToArray.length; compareToIndex++) {
        if (this.compareStrings(searchArray[searchIndex], compareToArray[compareToIndex])) {
          counter++;
        }
      }
    }
    return counter;
  }

  /*
  // Meat and potatoes of the code, does the word comparisons.
  compareStrings(searchFor: string, compareTo: string): boolean {
    searchFor = searchFor.toLowerCase();
    // strips numbers and symbols from a word.
    compareTo = compareTo.replace(/\W/g, '');
    if (searchFor === compareTo.toLowerCase()) {
      return true;
    }
    return false;
  }*/

   // Meat and potatoes of the code, does the word comparisons by character values instead of whole words.
   compareStrings(searchFor: string, compareTo: string): boolean {
    searchFor = searchFor.toLowerCase();
    // building string to compareTo...
    for (let stringIndex = 0; stringIndex <= compareTo.length - searchFor.length; stringIndex++) {
      let buildingString = '';
      for (let searchLength = 0; searchLength < searchFor.length; searchLength++) {
        buildingString = buildingString + compareTo[stringIndex + searchLength];
      }
      // finished string
      const builtString = buildingString.toLowerCase();
      if (searchFor === builtString) {
        return true;
      }
    }
    return false;
  }

  // Sort results in relevenace to how many matches were found to be true.
  sortResults(ascOrders: any[]): Order[] {
    const tempLength = ascOrders.length;
    const orderToReturn = [];
    for (let j = 0; j < tempLength; j++) {
      let index = 0;
      let high = 0;
      for (let i = 0; i < ascOrders.length; i++) {
        if (high < ascOrders[i].amountSame) {
          high = ascOrders[i].amountSame;
          index = i;
        }
      }
      orderToReturn.push(ascOrders[index].anOrder);
      ascOrders.splice(index, 1);
    }
    return orderToReturn;
  }

  orderPub() {
    if ( this.pub === 'pubDESC' ) {
      this.pub = 'pubASC';
    } else {
      this.pub = 'pubDESC';
    }
    this.orderService.reOrder(this.pub);
  }

  orderTitles() {
    if (this.titles === 'titleDESC') {
      this.titles = 'titleASC';
    } else {
      this.titles = 'titleDESC';
    }
    this.orderService.reOrder(this.titles);
  }

  orderNums() {
    if (this.order === 'DESC') {
      this.order = 'ASC';
    } else {
      this.order = 'DESC';
    }
    this.orderService.reOrder(this.order);
  }

  openDialog(order: Order): void {
    const dialogRef = this.dialog.open(DeleteOrderComponent, {
      data: {
        anOrder: order
      }
    });
    dialogRef.afterClosed().subscribe(result => {
      if ( result === 'Delete') {
        this.onDelete(order._id);
      }
    });
  }

  editOrder(order: Order): void {
    const dialogRef = this.dialog.open(EditOrderComponent, {
      data: {
        anOrder: order
      }
    });
    dialogRef.afterClosed().subscribe();
  }

  orderYearsToShow(order: Order): boolean {
    if ( (order.isPub || (!order.isPub && this.isAdmin === true)) && order.date.toString().slice(0, 4) === this.currentYear.toString()) {
      return true;
    } else if ( (order.isPub || (!order.isPub && this.isAdmin === true)) && this.currentYear.toString() === 'All Years' ) {
      return true;
    } else { return false; }
  }

  onDelete(_id: number) {
    this.orderService.deleteOrder(_id);
  }
}

An example output would be if someone entered: "Sub" the function would match with "Subpoena". There is an alternative method that would require the entire word to match.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.