如果彼此相邻,一起加入星期几

时间:2017-08-26 13:59:25

标签: javascript

我有一个可以包含一周中所有日期的数组

["mon", "tues", "wed", "thur", "fri", "sat", "sun"]

我正在尝试找出一个可以产生以下内容的好脚本

数组包含

["mon", "tues", "fri", "sat", "sun"]

输出一串 Mon-Tues & Fri - Sun

我知道我可以使用if语句明显地做到这一点,但我想不出一个好的/聪明的方法来做到这一点。

5 个答案:

答案 0 :(得分:4)

3.98569e+12 5.08741e+06  62753.4  58133.2  26340.8  20529.1 15839.4 1050.96

In action

高层代码将数组分组为连续的日组,然后加入它们:

const days = ["mon", "tues", "wed", "thur", "fri", "sat", "sun"];

function group(arr){
  let result = [ [] ], current = result [0];

  for(const day of arr){
    if(days.indexOf(current[current.length-1]) + 1 === days.indexOf(day)) {
      current.push(day);
    } else {
     current = [day];
     result.push(current);
   }
  }

  return result
    .filter(el => el.length)
    .map(el => el.length > 1 ? el[0] +"-"+ el.pop() : el[0])
    .join(" & ");
}

答案 1 :(得分:2)

您可以收集am数组中的所有天数范围,并在结构中呈现结果,您需要。

此提案也适用于周日范围。



var days = ["mon", "tues", "wed", "thur", "fri", "sat", "sun"],
    data = ["mon", "tues", "fri", "sat", "sun"],
    dayNo = {},
    result;

days.forEach((d, i) => dayNo[d] = i);

result = data
    .reduce((r, d, i, dd) => {
        if ((dayNo[dd[i - 1]] + 1) % 7 === dayNo[d]) {
            r[r.length - 1][1] = d;
        } else {
            r.push([d]);
        }
        return r;
    }, [])
    .map(r => r.join(' - '))
    .join(' & ');

console.log(result);




答案 2 :(得分:0)

花了一些时间来比较三个提案,以检查无效输入的行为,并检查总执行时间

var reference = ["mon", "tues", "wed", "thur", "fri", "sat", "sun"];

var testcases = [
["mon", "tues", "wed", "thur", "fri", "sat", "sun"],
["mon", "tues", "fri", "sat", "sun"],
["mon", "wed", "fri", "sun"],
["mon", "dupa", "test", "halo", "fri", "sat", "sun"],
["sat", "", "fri", "sat", "sun"],
["wed", "mon", "fri", "tues"],
[""],
[]];

// https://stackoverflow.com/questions/1026069/how-do-i-make-the-first-letter-of-a-string-uppercase-in-javascript
function capitalizeFirstLetter(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}

function Marcin(ct, ref) {
    var i0 = 0;
    var i1 = 0;
    var state = 0; // 0 initial 1 later initial 2 inside
    var result = "";
    var len = 0;
    if (ct.length === 0)
        return "";
    while(i0 <= ct.length && i1 <= ref.length) {
    switch(state) {
        case 0:
        case 1:
            while(i1<ref.length && ct[i0] != ref[i1++]);
            if(state == 1)
                result += ' & ';
            result += capitalizeFirstLetter(ct[i0++]);
            state = 2;
            len = 0;
            break;
        case 2:
            if((i0 >= ct.length || i1 >= ref.length) || (ct[i0] != ref[i1])) {
                i0--;
                if (len)
                    result += '-' + capitalizeFirstLetter(ct[i0]);
                state = 1;
            }
            i0++;
            i1++;
            len++;
            break;
    }
    }
    return result;

}

var dayNo = {};
reference.forEach((d, i) => dayNo[d] = i);
//// I modified it here to move building of hash outside of the function

function Nina(data, days) {

  var result;

result = data
    .reduce((r, d, i, dd) => {
        if ((dayNo[dd[i - 1]] + 1) % 7 === dayNo[d]) {
            r[r.length - 1][1] = d;
        } else {
            r.push([d]);
        }
        return r;
    }, [])
    .map(r => r.join(' - '))
    .join(' & ');
   return result;
}

function Jonas(arr, days){
  var result = [ [] ], current = result [0];

  for(var day of arr){
    if( days.indexOf( current[current.length-1] ) +1 === days.indexOf( day) ){
      current.push(day);
    }else{
     current = [day];
     result.push( current);
   }
  }

  return result
    .filter(el => el.length)
    .map(el=> el.length > 1?el[0] +"-"+ el.pop():el[0])
    .join(" & ");
}

var functions=[Marcin, Nina, Jonas];
var vlog = ""
function vlogger(x) {vlog += x + "\n"};

functions.forEach((cv) => {
    vlogger("testing function " + cv.name);
    testcases.forEach((tc) => {
        vlogger("* input " + tc);
        vlogger("* outpt " + cv(tc,reference));
    });    
    var n = 100000;
    var d1 = new Date();
    while(n--) {
        cv(testcases[1], reference);
    }
    var d2 = new Date();
    vlogger("* time " + (d2 - d1));
});

console.log(vlog);

令人惊讶的是,添加哈希表对整体性能没有多大帮助。甚至一旦我修改了原始代码,只建立了一次哈希。解决方案的不同之处还在于它们如何反对无序和不合适的输入。

testing function Marcin
* input mon,tues,wed,thur,fri,sat,sun
* outpt Mon-Sun
* input mon,tues,fri,sat,sun
* outpt Mon-Tues & Fri-Sun
* input mon,wed,fri,sun
* outpt Mon & Wed & Fri & Sun
* input mon,dupa,test,halo,fri,sat,sun
* outpt Mon & Dupa
* input sat,,fri,sat,sun
* outpt Sat & 
* input wed,mon,fri,tues
* outpt Wed & Mon
* input 
* outpt 
* input 
* outpt 
* time 62
testing function Nina
* input mon,tues,wed,thur,fri,sat,sun
* outpt mon - sun
* input mon,tues,fri,sat,sun
* outpt mon - tues & fri - sun
* input mon,wed,fri,sun
* outpt mon & wed & fri & sun
* input mon,dupa,test,halo,fri,sat,sun
* outpt mon & dupa & test & halo & fri - sun
* input sat,,fri,sat,sun
* outpt sat &  & fri - sun
* input wed,mon,fri,tues
* outpt wed & mon & fri & tues
* input 
* outpt 
* input 
* outpt 
* time 170
testing function Jonas
* input mon,tues,wed,thur,fri,sat,sun
* outpt mon-sun
* input mon,tues,fri,sat,sun
* outpt mon-tues & fri-sun
* input mon,wed,fri,sun
* outpt mon & wed & fri & sun
* input mon,dupa,test,halo,fri,sat,sun
* outpt mon & dupa & test & halo & fri-sun
* input sat,,fri,sat,sun
* outpt sat &  & fri-sun
* input wed,mon,fri,tues
* outpt wed & mon & fri & tues
* input 
* outpt 
* input 
* outpt 
* time 142

答案 3 :(得分:0)

如何创建一个索引数组(每个索引为+1,所以它将为[1、2、3 ..],我们可以执行%进行延续,例如:再次sun > mon)您最初几天的实际位置是多少?这样,我们可以将每个值与最后一个值进行比较,如果差异不是1,那么我们将开始一个新组,否则继续使用现有组。

让我们假设您已经输入了["mon","tues", "fri"],我们会将其映射到[1,2,5],以便我们可以迭代数组并获得与前一个的差异。让我们创建一个有效的代码段!

function evaluateContinuation(ip) {
    var days = ["mon", "tues", "wed", "thur", "fri", "sat", "sun"];
    return ip.map(day => 1 + days.indexOf(day)).reduce(function(r, n, i, a) {
        n - a[i-1] % 7 != 1 && r.push([]);
        return r[r.length-1].splice(1, 1, days[n-1]) && r;
    }, []).map(g => g.join('-')).join(' & ');
}

console.log(evaluateContinuation(["mon", "tues", "wed"]))
console.log(evaluateContinuation(["tues", "wed", "fri", "sat", "sun", "mon"]))
console.log(evaluateContinuation(["mon", "wed", "fri", "sat", "sun"]))

答案 4 :(得分:-1)

解决这个问题真的很有趣!希望这对你有用,享受并且不要忘记给予学分:)

// your code goes here
var reference = ["mon", "tues", "wed", "thur", "fri", "sat", "sun"];

// https://stackoverflow.com/questions/1026069/how-do-i-make-the-first-letter-of-a-string-uppercase-in-javascript
function capitalizeFirstLetter(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}

function vmap1(ct, ref) {
    var i0 = 0;
    var i1 = 0;
    var state = 0; // 0 initial 1 later initial 2 inside
    var result = "";
    var len = 0;
    while(i0 <= ct.length && i1 <= ref.length) {
    switch(state) {
        case 0:
        case 1:
            while(i1<ref.length && ct[i0] != ref[i1++]);
            if(state == 1)
                result += ' & ';
            result += capitalizeFirstLetter(ct[i0++]);
            state = 2;
            len = 0;
            break;
        case 2:
            if((i0 >= ct.length || i1 >= ref.length) || (ct[i0] != ref[i1])) {
                i0--;
                if (len)
                    result += '-' + capitalizeFirstLetter(ct[i0]);
                state = 1;
            }
            i0++;
            i1++;
            len++;
            break;
    }
    }
    return result;
}

print(vmap1(["mon", "tues", "wed", "thur", "fri", "sat", "sun"], reference));
print(vmap1(["mon", "tues", "fri", "sat", "sun"], reference));
print(vmap1(["mon", "wed", "fri", "sun"], reference));

结果:

Mon-Sun
Mon-Tues & Fri-Sun
Mon & Wed & Fri & Sun