我正在研究一种算法来查找对象的JSON数组中的句点。 JSON数组如下:
[
{
"year": 1960,
"month": 1,
"colval": 1
},
{
"year": 1960,
"month": 2,
"colval": 1
},
{
"year": 1960,
"month": 3,
"colval": 0
},
....
....
{
"year": 2016,
"month": 12,
"colval": 0
}]
此数组由包含"年","月"的对象组成。和" colval"。 (colval只能是0,1,2和3)
阵列从1960-1到2016-12开始,我希望获得colval> 0,此期间只能有1个零值。如果零值重复两次,则不计入期间。并且期限必须至少持续6个月。
例如:(仅显示colval的值)
粗体值是选定的时间段。
1-2-1-3-0-0-0-的 1-1-1-2-2-3-2-1-3-3-2 -0-0- 0- 1-2-2-2-0-3-3-3-3 -0-0-0-1-0-1-0-的 2-0-2- 2-3-3-3
我尝试用纯JS计算值,如果它大于0,当我访问两个"零"时将其设为零,但我仍然没有得到开始和结束的句点。
以下是我正在处理的代码:
var counter = 0;
var zeroCounter = 0;
var startArray = null;
var periods = [];
$.each(groupArr, function (i, v) {
if (v.colval > 0) {
if (counter == 0) {
startArray = v;
}
counter++;
}
else {
if (zeroCounter > 1) {
if (counter > 5) {
endArray = v;
periods.push({ start: startArray, end: v });
startArray = null;
counter = 0;
}
}
else {
zeroCounter++;
}
}
});
更新1:序列也无法以"零"开始或结束。
更新2:今天还增加了一项要求,即如果出现零之间有12个月,则此零也将添加到期间并继续其他数字。例如:
0-0- 1-1-0-1-2-2-1-3-1-2-2-3-2-2-3-0-2-1-1-3- 2 -0-0
更新3:由于"减少" IE中的函数支持,方法应该在Underscore中实现,以绕过浏览器支持问题。
更新4:新示例:
- &GT; 1-2-1-3-0-0-0-的 1-1-1-2-2-3-2-1-3-3-2 -0-0-0- < b> 1-2-2-2-0-3-3-3-3 -0-0-0-1-0-1-0-2-0-2-2-3-3- 3
- &GT; 0-0- 1-1-0-1-2-2-1-3-1-2-2-3-2-2-3-0-2-1-1-3-2 -0-0
- &GT; 1-1-3-0-1-0-0-的 1-0-1-2-3-2-2-2-3-1 -0-1-2-3-0 -1-2-0-0-0-1-2-3-3
答案 0 :(得分:0)
你可以这样做:
var arr = [{"year": 1960,"month": 1,"colval": 1},{"year": 1960,"month": 10,"colval": 1},{"year": 1960,"month": 3,"colval": 0},{"year": 2016,"month": 12,"colval": 0 }];
var periods = arr.reduce((a, c, index, array) => {
if(c.colval == 0 && index < (array.length - 1) && array[index + 1].colval == 0 && a[a.length - 1].length || (c.colval == 0 && a[a.length - 1].some(v => c.colval == 0))){
a.push([]);
}else{
a[a.length - 1].push(c);
}
return a;
}, [[]]).reduce((a, c) => {
if(c.length >= 2){
c.sort((v1, v2) => ((v1.year + v1.month) - (v2.year + v2.month)));
var minMonths = (c[0].year * 12) + c[0].month;
var maxMonths = (c[c.length - 1].year * 12) + c[c.length - 1].month;
if(maxMonths - minMonths >= 6){
a.push(c);
}
}
return a;
}, []);
console.log(periods)
当reduce
等于colval
的两个连续对象出现或者当前对象的0
等于colval
时,第一个0
会创建一个新句点。在当前时期已经存在这样一个对象。
第二次减少仅保留大于或等于6个月的时段。
你可能想要简化第一个if
中的reduce
语句,我可能会让它变得更加复杂。
答案 1 :(得分:0)
let values = [
{ "year": 1960, "month": 1, "colval": 1 },
{ "year": 1960, "month": 2, "colval": 1 },
{ "year": 1960, "month": 3, "colval": 2 },
{ "year": 1960, "month": 4, "colval": 0 },
{ "year": 1960, "month": 5, "colval": 2 },
{ "year": 1960, "month": 6, "colval": 3 },
{ "year": 1960, "month": 7, "colval": 0 },
{ "year": 1960, "month": 8, "colval": 0 },
{ "year": 1960, "month": 9, "colval": 2 },
{ "year": 1960, "month": 10, "colval": 3 },
{ "year": 1960, "month": 11, "colval": 1 },
{ "year": 1960, "month": 12, "colval": 2 },
{ "year": 1961, "month": 1, "colval": 1 },
{ "year": 1961, "month": 2, "colval": 3 },
{ "year": 1961, "month": 3, "colval": 0 },
{ "year": 1961, "month": 4, "colval": 1 },
{ "year": 1961, "month": 5, "colval": 0 }
]
function getPeriods(months) {
let periods = []; // this is an array of periods
let prevInPeriod = false;
let currPeriod;
let zeros = 0;
months.forEach(function (month) {
let currIsZero = (month.colval === 0);
let currInPeriod = !currIsZero || !zeros;
if (!prevInPeriod && currIsZero) {
currInPeriod = false;
}
if (!month.colval) {
zeros++;
}
if (!prevInPeriod && !currInPeriod) {
return;
}
if (!prevInPeriod && currInPeriod) { // entering period
currPeriod = [month]; // creating new period with date
} else if (prevInPeriod && currInPeriod) { // still in period
currPeriod.push(month); // pushing new values
} else if (prevInPeriod && !currInPeriod) { // period ends
periods.push(currPeriod); // saving current period into results
zeros = 0;
}
prevInPeriod = currInPeriod;
});
// checking the last period if it's in a results
if (periods[periods.length - 1] !== currPeriod) {
periods.push(currPeriod);
}
// filtering out periods which are shorter than 6
periods = periods.filter(period => period.length >= 6);
return periods;
}
这里有jsfiddle测试:https://jsfiddle.net/7awg75rh/1/