【问题标题】:Compare 2 JSON objects and find best time JavaScript比较 2 个 JSON 对象并找到最佳时间 JavaScript
【发布时间】:2020-10-17 21:21:38
【问题描述】:

我试图弄清楚如何根据 JSON 对象中的用户键从 2 个 JSON 对象中找到最佳时间,并构建正确的数组以显示具有最佳结果的块。

第一个 JSON 对象:

[
{
        "user1": "00:31.889",
        "user2": "00:32.739",
        "user3": "01:00.515",
        "user4": "00:28.336",
        "user5": "00:35.745"
    },
    {
        "user1": "00:26.470",
        "user2": "00:30.063",
        "user3": "00:28.696",
        "user4": "00:30.248",
        "user5": "00:35.123"
    },
    {
        "user1": "00:26.956",
        "user2": "00:33.588",
        "user3": "00:30.021",
        "user4": "00:29.154",
        "user5": "00:38.492"
    },
    {
        "user1": "00:27.190",
        "user2": "00:32.307",
        "user3": "00:30.467",
        "user4": "00:30.189",
        "user5": "00:39.669"
    },
    {
        "user1": "00:27.368",
        "user2": "00:28.124",
        "user3": "00:29.960",
        "user4": "00:29.649",
        "user5": "00:42.450"
    }
]

第二个对象:

[
    {
        "key": "user1",
        "label": "Alex"
    },
    {
        "key": "user2",
        "label": "Jane"
    },
    {
        "key": "user3",
        "label": "Frank"
    },
    {
        "key": "user4",
        "label": "Merlyn"
    },
    {
        "key": "user5",
        "label": "Josh"
    }
]

返回应该是这样的:[{name: 'Alex', value: 233433}]

尝试了许多选项,包括 Object.key,但仍然找不到解决方案。

【问题讨论】:

    标签: javascript arrays json object


    【解决方案1】:

    了解我的善良

    const results = [
        {
            "user1": "00:31.889",
            "user2": "00:32.739",
            "user3": "01:00.515",
            "user4": "00:28.336",
            "user5": "00:35.745"
        },
        {
            "user1": "00:26.470",
            "user2": "00:30.063",
            "user3": "00:28.696",
            "user4": "00:30.248",
            "user5": "00:35.123"
        },
        {
            "user1": "00:26.956",
            "user2": "00:33.588",
            "user3": "00:30.021",
            "user4": "00:29.154",
            "user5": "00:38.492"
        },
        {
            "user1": "00:27.190",
            "user2": "00:32.307",
            "user3": "00:30.467",
            "user4": "00:30.189",
            "user5": "00:39.669"
        },
        {
            "user1": "00:27.368",
            "user2": "00:28.124",
            "user3": "00:29.960",
            "user4": "00:29.649",
            "user5": "00:42.450"
        }
    ]
    
    const users = [
        {
            "key": "user1",
            "label": "Alex"
        },
        {
            "key": "user2",
            "label": "Jane"
        },
        {
            "key": "user3",
            "label": "Frank"
        },
        {
            "key": "user4",
            "label": "Merlyn"
        },
        {
            "key": "user5",
            "label": "Josh"
        }
    ]
    
    const stringToObject = (str) => {
      const m = +str.split(":")[0];
      const s = +str.split(":")[1].split(".")[0];
      const ms = +str.split(":")[1].split(".")[1];
      return {m, s, ms}
    }
    
    const stringToMs = (str) => {
      const {m, s, ms} = stringToObject(str)
      return( m * 60 * 1000) + (s * 1000) + ms;
    }
    
    const getBestResults = () =>{
      const output = []
      for(let user of users){
         let min = Infinity;
         for(let result of results){
            const time = stringToMs(result[user["key"]])
            min = Math.min(time, min)
         }
         output.push({name: user["label"], value: min})
      }
      return output;
    }
    
    console.log(getBestResults())
    
    

    solution JsBin

    这个 O(n^) 但可能你不在乎。

    【讨论】:

      【解决方案2】:

      一步一步的解决方案

      我认为你可以用两行 Javascript 来做到这一点。

      观察你只需要知道整个时间列表中最低的时间,然后给出那个人的身份。

      第1行.查找最短时间的userId和时间

      • 将每个 5 元素的对象转换成一个数组,这样前 5 次就存储为一个数组:[ ["user 1", "00:31.889"], ["user 2", ...] ] ,接下来的 5 个在另一个数组中,等等。一个好的方法是 .map 使用函数 Object.entries 的原始大数组。

      • 将您将拥有的 5 个不同的数组展平为一个长数组。这将包含用户 1 的 5 次、用户 2 的 5 次等。Javascript .flat() 函数将为您执行此操作。

      • 获取时间最短的 userId-and-time 对。由于时间都是包含相同格式的数值的所有字符串,带有前导零,因此您可以按字母顺序对它们进行排序并获取结果列表的元素 #0。一种方便的方法是使用 Javascript .sort() 函数。您想告诉排序程序查看每个微型数组的第 [1] 个元素,即时间,而不是作为用户 ID 的第 [0] 个元素(例如“用户 1”)。

      该步骤序列的代码是:

      times.map(Object.entries).flat().sort((a,b)=>a[1].localeCompare(b[1]))[0]
      

      第 2 行。获取获胜用户的用户名

      • 从用户列表中,您要选择与获胜用户具有相同 ID 的用户。您可以为此使用 Javascript .filter 函数。获胜用户的 ID 是 win[0],即 id-time 对中两个项目中的第一个。获取过滤函数来测试每个用户的ID。

      • Javascript 会给你一个列表,里面有一个项目。你想要第一个项目,即 [0]。

      • 显示该人的姓名 (.label) 和获胜时间 (winning[1])。

      代码如下:

      users.filter(user=>user.key===winning[0]) [0] .label,winning[1]
      

      我没有尝试将分钟和秒转换为秒,因为我相信您知道如何做到这一点,并且您的示例正确答案似乎与上面的数据不匹配。大概您只是显示所需信息的类型,而不是指定转换。

      下面的代码应该可以满足您的需求。如果有什么需要解释的,请告诉我。

      const times = [{
          "user1": "00:31.889",
          "user2": "00:32.739",
          "user3": "01:00.515",
          "user4": "00:28.336",
          "user5": "00:35.745"
        },
        {
          "user1": "00:26.470",
          "user2": "00:30.063",
          "user3": "00:28.696",
          "user4": "00:30.248",
          "user5": "00:35.123"
        },
        {
          "user1": "00:26.956",
          "user2": "00:33.588",
          "user3": "00:30.021",
          "user4": "00:29.154",
          "user5": "00:38.492"
        },
        {
          "user1": "00:27.190",
          "user2": "00:32.307",
          "user3": "00:30.467",
          "user4": "00:30.189",
          "user5": "00:39.669"
        },
        {
          "user1": "00:27.368",
          "user2": "00:28.124",
          "user3": "00:29.960",
          "user4": "00:29.649",
          "user5": "00:42.450"
        }
      ];
      
      const users = [{
          "key": "user1",
          "label": "Alex"
        },
        {
          "key": "user2",
          "label": "Jane"
        },
        {
          "key": "user3",
          "label": "Frank"
        },
        {
          "key": "user4",
          "label": "Merlyn"
        },
        {
          "key": "user5",
          "label": "Josh"
        }
      ];
      
      // Line 1. Get the lowest time across all users and all attempts
      const winning = times.map(Object.entries).flat().sort((a,b)=>a[1].localeCompare(b[1]))[0]
      
      // Line 2. Display their identity and time
      console.log(users.filter(user=>user.key===winning[0])[0].label,winning[1])

      【讨论】:

      • 感谢您的精彩解释,现在更清楚了。如何为每个用户输出最佳结果?我试图删除获胜者末尾的索引以输出完整的用户列表,但一直不被拒绝。
      【解决方案3】:

      如果您想为每个用户获得最好的分数,您需要不同的策略

      我之前的回答是基于您想要整个比赛的获胜者的时间,而不是每个跑步者的最佳时间。

      我的解决方案是按时间顺序对所有 userIds-and-times 进行排序。那么在该数组中,“user1”的最佳时间是“user1”在该有序列表中第一次出现。

      const times = [{
          "user1": "00:31.889",
          "user2": "00:32.739",
          "user3": "01:00.515",
          "user4": "00:28.336",
          "user5": "00:35.745"
        },
        {
          "user1": "00:26.470",
          "user2": "00:30.063",
          "user3": "00:28.696",
          "user4": "00:30.248",
          "user5": "00:35.123"
        },
        {
          "user1": "00:26.956",
          "user2": "00:33.588",
          "user3": "00:30.021",
          "user4": "00:29.154",
          "user5": "00:38.492"
        },
        {
          "user1": "00:27.190",
          "user2": "00:32.307",
          "user3": "00:30.467",
          "user4": "00:30.189",
          "user5": "00:39.669"
        },
        {
          "user1": "00:27.368",
          "user2": "00:28.124",
          "user3": "00:29.960",
          "user4": "00:29.649",
          "user5": "00:42.450"
        }
      ];
      
      const users = [{
          "key": "user1",
          "label": "Alex"
        },
        {
          "key": "user2",
          "label": "Jane"
        },
        {
          "key": "user3",
          "label": "Frank"
        },
        {
          "key": "user4",
          "label": "Merlyn"
        },
        {
          "key": "user5",
          "label": "Josh"
        }
      ];
      
      // Line 1. Sort the user-and-time data into order of time, shortest first.
      
      const orderedTimes = times.map(Object.entries).flat().sort((a,b)=>a[1].localeCompare(b[1]))
      
      // Line 2. Loop over each user, using "users.map", and for each user, filter ONLY the user-and-time elements that feature THAT user. Of that list of user-and-time elements, only take the first one, i.e. [0]. That will be that user's best time.
      
      const usersKeyAndBestTime = users.map(user=>orderedTimes.filter(userKeyAndTime=>userKeyAndTime[0]===user.key)[0]
      );
      
      // Line 3. Output the result, replacing the user key ("user1") with their actual name.
      
      console.log(
          usersKeyAndBestTime.map(
              keyAndBestTime=>[
                  users.filter(
                      user=>user.key===keyAndBestTime[0]
                   )[0].label,
                   keyAndBestTime[1]
               ]
          )
      )

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-23
        • 2016-01-15
        • 1970-01-01
        • 1970-01-01
        • 2011-05-26
        • 1970-01-01
        • 2011-12-27
        • 1970-01-01
        相关资源
        最近更新 更多