Javascript - Поиск победителя пиццы из JSON - PullRequest
0 голосов
/ 20 июня 2020

Любой покупатель, который заказывает пиццу с тремя топпингами с уникальной комбинацией начинок для всех пицц во всех магазинах в течение этого месяца, получит купон на бесплатную пиццу по электронной почте (если он предоставит свой адрес электронной почты).

Вот два метода определения победителя. Но ни один из этих методов не работает должным образом. Я не уверен, в чем ошибка. Также какой набор данных я должен использовать для тестирования этих реализаций? Как я могу решить эту проблему с помощью запросов к базе данных?

// Here is the json array and functions:
const inputArray = [{"email": "email1@example.com", "toppings":
    ["Mushrooms","Pepperoni","Peppers"]},
    {"email": "email2@example.com", "toppings":
    ["Cheddar","Garlic","Oregano"]},
    {"email": "email3@example.com", "toppings": ["Bacon","Ham","Pineapple"]},
    {"email": "", "toppings": ["Parmesan","Tomatoes"]},
    {"email": "email4@example.com", "toppings":
    ["Mushrooms","Pepperoni","Peppers"]},
    {"email": "", "toppings": ["Cheddar","Tomatoes"]},
    {"email": "email5@example.com", "toppings": ["Bacon","Ham","Pineapple"]},
    {"email": "email6@example.com", "toppings": ["Beef","Parmesan"]},
    {"email": "", "toppings": ["Onions","Pepperoni"]},
    {"email": "", "toppings": ["Bacon","Ham","Pineapple"]}]


function printWinners1(inputArray) {
  // Perform a QuickSort on the array.
  inputArray.sort((a, b) => {
    // Convert each toppings array to a string and do a string comparison
    return a.toppings.toString().localeCompare(b.toppings.toString());
  });
  let previousEmail = '';
  let previousToppingsAsString = '';
  let previousToppingCount = 0;
  let numberOfSimilarOrders = 0;
  // Iterate through the array, with "order" being each item in the  array.
  inputArray.map((order) => {
    let toppingsAsString = order.toppings.toString();
    if (toppingsAsString === previousToppingsAsString) {
      numberOfSimilarOrders++;
    } else {
      if ((numberOfSimilarOrders === 1) && 
          (previousToppingCount === 3) && 
          (previousEmail) !== '') {
        // Print out the email.
        console.log(previousEmail);
      }
      previousToppingsAsString = toppingsAsString;
      previousEmail = order.email;
      previousToppingCount = order.toppings.length;
      numberOfSimilarOrders = 1;
    }
  });
}

function printWinners2(inputArray) {
  let hashTable = new Map();
  // Iterate through the array, with "order" being each item in the array.
  inputArray.map((order) => {
    if ((order.toppings.length === 3) && (order.email !== '')) {
      let toppingsAsString = order.toppings.toString();
      let matchingValue = hashTable.get(toppingsAsString);
      if (matchingValue) {
        // This key was already in the hash table.
        // matchingValue is a reference to the object in the hash table.
        matchingValue.duplicate = true;
      } else {
        // Insert into the hash table, using the toppings as the           key and an object containing the email as the value.
        hashTable.set(toppingsAsString, {
          email: order.email,
          duplicate: false
        });
      }
    }
  });
  // Iterate through the values in the hash table, with "value" being each value.
  hashTable.forEach((value) => {
    if (!value.duplicate) {
      // Print out the email.
      console.log(value.email);
    }
  });
}
printWinners1(inputArray)

Ответы [ 3 ]

0 голосов
/ 20 июня 2020

Вот мой взгляд на это.

I go через ваш список заказов и переставить его в объект («ха sh») в соответствии с выбранными тройками начинки. Начинки сортируются так, чтобы порядок их упоминания не имел значения.

Затем я снова просматриваю их, чтобы проверить их уникальность. Результатом является массив массивов: каждый подмассив содержит начальную комбинацию, за которой следует массив из одного элемента электронных писем победителей.

const inputArray = [{"email": "email1@example.com", "toppings":
["Mushrooms","Pepperoni","Peppers"]},
{"email": "email2@example.com", "toppings":
["Cheddar","Garlic","Oregano"]},
{"email": "email3@example.com", "toppings": ["Bacon","Ham","Pineapple"]},
{"email": "", "toppings": ["Parmesan","Tomatoes"]},
{"email": "email4@example.com", "toppings":
["Mushrooms","Pepperoni","Peppers"]},
{"email": "", "toppings": ["Cheddar","Tomatoes"]},
{"email": "email5@example.com", "toppings": ["Bacon","Ham","Pineapple"]},
{"email": "email6@example.com", "toppings": ["Beef","Parmesan"]},
{"email": "", "toppings": ["Onions","Pepperoni"]},
{"email": "", "toppings": ["Bacon","Ham","Pineapple"]}];

var win=Object.entries(inputArray.reduce((a,c)=>{
  if (c.toppings.length==3){
let top=c.toppings.sort().join('_');
if (c.email) (a[top]=a[top]||[]).push(c.email);
  }
  return a;
}, {})).filter(([t,m])=>m.length==1);

console.log(win);
// The actual list of winners is extracted like this:
console.log(win.map(c=>c[1][0]))
0 голосов
/ 20 июня 2020

Это будет работать !!!

Я проверил 4 условия здесь:

  1. адрес электронной почты не должен быть пустым.

  2. длина начинки должна быть равна трем.

  3. В массиве результатов не должно быть дубликатов.

  4. уникальная проверка начинки

var inputArray = [{"email": "email1@example.com", "toppings":
    ["Mushrooms","Pepperoni","Peppers"]},
    {"email": "email2@example.com", "toppings":
    ["Cheddar","Garlic","Oregano"]},
    {"email": "email3@example.com", "toppings": ["Bacon","Ham","Pineapple"]},
    {"email": "", "toppings": ["Parmesan","Tomatoes"]},
    {"email": "email4@example.com", "toppings":
    ["Mushrooms","Pepperoni","Peppers"]},
    {"email": "", "toppings": ["Cheddar","Tomatoes"]},
    {"email": "email5@example.com", "toppings": ["Bacon","Ham","Pineapple"]},
    {"email": "email6@example.com", "toppings": ["Beef","Parmesan"]},
    {"email": "", "toppings": ["Onions","Pepperoni"]},
    {"email": "", "toppings": ["Bacon","Ham","Pineapple"]}];

function printWinners(inputArr) {
    var res = [];
    for(var i= 0; i<inputArr.length; i++) {
        if(inputArr[i]['email'] !== '' && inputArr[i]['toppings'].length === 3 && !res.find(item => item['email'] === inputArr[i]['email']) && (new Set(inputArr)).size === inputArr.length) {
            res.push(inputArr[i]);
      }

    }
    return res;
}

console.log(printWinners(inputArray));
0 голосов
/ 20 июня 2020

Я возился с ним сейчас на jsfiddle, чтобы посмотреть, смогу ли я сделать что-нибудь для ваших результатов. Первое, что бросается в глаза, это то, что у вас есть следующее:

inputArray.sort((a, b) => {
    // Convert each toppings array to a string and do a string comparison
    return a.toppings.toString().localeCompare(b.toppings.toString());
  });

Массив сортировки не мутирует, что означает, что он возвращает отсортированный массив, вам нужно будет уловить это в переменной.

let sortedArray = inputArray.sort((a, b) => {
    // Convert each toppings array to a string and do a string comparison
    return a.toppings.toString().localeCompare(b.toppings.toString());
  });

* Edit

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

https://jsfiddle.net/goofballtech/khv873ef/3/

function printWinners(){

// filter array down to email addresses and 3 topping pizza's
  let onlyEmails = orders.filter(order => order.email && order.toppings.length === 3)

// change orders to have sorted toppings and add a place to track similar order, then sort the entire list by order toppings
  let toppingsAsStrings = onlyEmails.map(order => {
    return {
      email: order.email,
      toppings: order.toppings.sort().toString(),
      similarOrders: 0,
    }
  }).sort((a, b) => {
    if (a.toppings.toLowerCase() < b.toppings.toLowerCase()) {
      return -1
    } else if (a.toppings.toLowerCase() > b.toppings.toLowerCase()) {
      return 1
    } else {
      return 0
    }
  })

  // check each order against it neighbors marking it if two of them match
 for (let i = 0; i < toppingsAsStrings.length; i++){
    if (i == 0) {
      toppingsAsStrings[i].toppings === toppingsAsStrings[i + 1].toppings ? toppingsAsStrings[i].similarOrders = 1 : null
    } else if (i == toppingsAsStrings.length - 1) {
      toppingsAsStrings[i].toppings === toppingsAsStrings[i - 1].toppings ? toppingsAsStrings[i].similarOrders = 1 : null
    } else {
      toppingsAsStrings[i].toppings === toppingsAsStrings[i + 1].toppings ||
        toppingsAsStrings[i].toppings === toppingsAsStrings[i - 1].toppings ?
        toppingsAsStrings[i].similarOrders = 1 :
        null
    }
  }

//find the ones that did not have matches
  let winners = toppingsAsStrings.filter(order => !order.similarOrders)

  console.log(winners)
}

...