简体   繁体   English

JavaScript:在循环内优化循环

[英]JavaScript: Optimizing loop inside a loop inside a loop

I'm working with an API and it is spitting data back at me in an odd format. 我正在使用API​​,它正在以奇怪的格式向我吐出数据。 Or it is at least to me. 或者至少对我来说。 The data is the hours of operation for a store, I want to match them up in the way I need them in the front end (the application is written in Angular, uses two APIs so I need to get the API to work with my logic, I don't want to adapt to their format) 数据是商店的营业时间,我想按照前端所需的方式进行匹配(该应用程序是用Angular编写的,使用两个API,所以我需要使该API与我的逻辑配合使用,我不想适应其格式)

This is the format the data is coming in from the API: 这是数据从API传入的格式:

var operatingHoursArray = [
    {Weds: true, End: "17:00", Start: "09:00"},
    {Tue: true, End: "17:00", Start: "09:00"},
    {Thur: true, End: "17:00", Start: "09:00"},
    {Sun: false, End: "", Start: ""},
    {Sat: true, End: "17:00", Start: "09:00"},
    {Mon: true, End: "17:00", Start: "09:00"},
    {Fri: true, End: "17:00", Start: "09:00"}
]

An odd structure IMO, I would have prefered the days of the week to be objects, then the open and closed hours stashed within them. 海事组织是一个奇怪的结构,我希望将星期几作为对象,然后将开放时间和封闭时间保存在其中。 My application (AngularJS) requires the data to be in the following format: 我的应用程序(AngularJS)要求数据采用以下格式:

var formattedHours = {
    Sunday: 'Closed',
    Monday: 'Closed',
    Tuesday: 'Closed',
    Wednesday: 'Closed',
    Thursday: 'Closed',
    Friday: 'Closed',
    Saturday: 'Closed'
};

Times defaults to 'Closed', this is the code I am using to match the day of the week with the format I require it in: Times默认为“关闭”,这是我用来将星期几与我要求的格式相匹配的代码:

var daysOfWeek = [
    { sform: 'Mon', lform: 'Monday' },
    { sform: 'Tue', lform: 'Tuesday' },
    { sform: 'Weds', lform: 'Wednesday' },
    { sform: 'Thur', lform: 'Thursday' },
    { sform: 'Fri', lform: 'Friday' },
    { sform: 'Sat', lform: 'Saturday' },
    { sform: 'Sun', lform: 'Sunday' }
];

// Loop through the operating hours for the dealer
for (var i = operatingHoursArray.length - 1; i >= 0; i--) {
    // Loop through the property names for each day, getting the first property name (the day of week)
    for (property in operatingHoursArray[i]) {
        // Loop through the days of the week
        for (var v = daysOfWeek.length - 1; v >= 0; v--) {
            // If the day of the week (array) matches the property name, get the details
            if(daysOfWeek[v].sform == property && operatingHoursArray[i][property] === true) {
                formattedHours[daysOfWeek[v].lform] = operatingHoursArray[i].Start + ' - ' + operatingHoursArray[i].End;
            }
        };
        break; // Forces loop to stop after first property
    }
};

This is getting really nasty really quick, but with my knowledge (noob level), I'm unsure of how to make this any more efficient. 这真是令人讨厌的事情,但是据我所知(菜鸟水平),我不确定如何提高效率。 It is working for what I need, but is there a better way to code this? 它可以满足我的需要,但是有没有更好的编码方法呢? Currently it has to run 49 times in order to check every day of the week. 目前,它必须运行49次才能检查一周的每一天。 As well, some stores do not provide 7 days of hours, instead only providing the hours they are open for. 同样,某些商店不提供7天的营业时间,而仅提供营业时间。 I can't change the structure of formattedHours because the other API is dependent on that same structure. 我不能更改formattedHours的结构,因为另一个API依赖于相同的结构。

Change daysOfWeek to an object: 将daysOfWeek更改为一个对象:

var daysOfWeek = {
    Mon: "Monday",
    Tue: "Tuesday",
    ...
};

Then you can just access daysOfWeek[property] instead of searching daysOfWeek with a loop. 然后,您可以只访问daysOfWeek[property]而不用循环搜索daysOfWeek

Start with a hash of short-to-long day names. 从短到长的日期名称开始。

var daysOfWeek = {
    'Mon': 'Monday',
    'Tue': 'Tuesday',
    'Weds': 'Wednesday',
    'Thur': 'Thursday',
    'Fri': 'Friday',
    'Sat': 'Saturday',
    'Sun': 'Sunday'
];

for (var i = operatingHoursArray.length - 1; i >= 0; i--) {
    // Loop through the property names for each day, getting the first property name (the day of week)
    for (property in operatingHoursArray[i]) {
        var dow = daysOfWeek[property];
        if(dow && operatingHoursArray[i][property]) {
            formattedHours[dow] = operatingHoursArray[i].Start + ' - ' + operatingHoursArray[i].End;
            break;
        }
    }
}

I'd take your ordered collection and iterate that. 我会带您订购的集合并进行迭代。 For each item, I'd loop the operatingHoursArray until one is found for the current daysOfWeek , then build your string. 对于每一项,我都会循环一次operatingHoursArray直到找到针对当前daysOfWeek ,然后构建您的字符串。

Using .forEach() and .every() cleans it up a little. 使用.forEach().every()对其进行一些清理。 The .every() is used for the inner loop so that we can halt the iteration once the match is found. .every()用于内部循环,以便一旦找到匹配项,我们就可以停止迭代。

var daysOfWeek = [
    { sform: 'Mon', lform: 'Monday' },
    { sform: 'Tue', lform: 'Tuesday' },
    { sform: 'Weds', lform: 'Wednesday' },
    { sform: 'Thur', lform: 'Thursday' },
    { sform: 'Fri', lform: 'Friday' },
    { sform: 'Sat', lform: 'Saturday' },
    { sform: 'Sun', lform: 'Sunday' }
];

daysOfWeek.forEach(function(day) {
    operatingHoursArray.every(function(item) {
         if (item.hasOwnProperty(day.sform)) {
             day.formatted = item.Start + ' - ' + item.End;
             day.start = item.Start;
             day.end = item.End;
             day.open = item[day.sform]
             return false;
         }
    });
});

Notice that I'm adding the formatted string, as well as the original data to your daysOfWeek objects. 请注意,我正在将格式化的字符串以及原始数据添加到您的daysOfWeek对象中。

This is so that you can keep the order you defined. 这样可以保留您定义的顺序。 So now you can look up by index, as well as iterate in a reliable order, which isn't possible when using for-in . 因此,现在您可以按索引查找,并以可靠的顺序进行迭代,这在使用for-in时是不可能for-in

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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