Javascript - 从 JSON 中找出披萨赢家

Javascript - Finding Pizza winner out of JSON

任何订购具有独特组合的三层比萨饼的客户 该月所有商店所有披萨的配料将通过电子邮件收到免费披萨的优惠券(如果他们提供电子邮件地址)。

这里有两种找出获胜者的方法。但是这些方法中的 none 可以正常工作。我不确定错误在哪里。我还应该使用哪个数据集来测试这些实现?我怎样才能用数据库查询解决这个问题?

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

我现在正在 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());
  });

排序数组没有发生变化,这意味着它 returns 排序后的数组,您需要在变量中捕获它。

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

*编辑

好的,我的解决方案更加分步和明确,因此您可以想象每个步骤以及发生的事情。我尝试将它的结构与您所拥有的结构类似,以便与您的初衷保持一致。

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

这是我的看法。

我查看了您的订单列表,并根据所选的顶部三胞胎将其重新排列在一个对象 ("hash") 中。对浇头进行排序以使它们被提及的顺序无关紧要。

然后我再次过滤它们以检查它们的唯一性。输出是一个数组数组:每个子数组包含顶部组合,后跟获胜者电子邮件的单项数组。

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

这行得通!!!

我在这里检查了 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));