根据对象值获取数组列表的“范围”

时间:2019-10-30 04:37:21

标签: javascript jquery

我的列表如下

[{"type":"A"},{"type":""},{"type":""},{"type":"B"},{"type":"C"},{"type":""},{"type":"A"},{"type":"A"},{"type":"D"},{"type":"C"}]

将某个类型之后的任何空类型视为该类型。

例如:{"type":"A"},{"type":""},{"type":""} 其中的三项归类为A

例如:{"type":"A"},{"type":"A"} 将列出范围为6-7,而不是6、7

我将如何获取每种类型的范围(按索引)。我正在寻找的输出是这样的:

 A: 0-2, 6-7
 B: 3
 C: 4-5, 9
 D: 8

3 个答案:

答案 0 :(得分:1)

您可以这样做:

const types = [{"type":"A"},{"type":""},{"type":""},{"type":"B"},{"type":"C"},{"type":""},{"type":"A"},{"type":"A"},{"type":"D"},{"type":"C"}]

const getStrIfCommas = (commas, c) => {
  const lastStr = commas[commas.length - 1]
  const lastStrResult = lastStr.includes('-')
    ? lastStr.replace(/\d+$/, c)
    : lastStr + `-${c}`
  return --commas.length
    ? `${commas.join(', ') || ''}, ${lastStrResult}`
    : lastStrResult
}

const getStrIfNextInt = (a, c) => {
  const commas = a.str.toString().split(', ')
  return commas.length
    ? getStrIfCommas(commas, c)
    : `${a.str}-${c}`
}

const getStrIfPrev = (a, c) => a.prev + 1 === c
  ? getStrIfNextInt(a, c)
  : a.str.length
    ? `${a.str}, ${c}`
    : ''

const result = Object
  .entries(types.reduce((a, { type }, i) => {
    if (type) {
      a[type] = a[type] || []
      a[type].push(i)
      a.prev = type
    } else if (a.prev) {
      a[a.prev].push(i)
    }
    return a
  }, {}))
  .reduce((acc, [k, indexes]) => {
    if (Array.isArray(indexes)) {
      acc[k] = indexes.reduce((a, c) => {
        a.str = a.hasOwnProperty('prev')
          ? getStrIfPrev(a, c)
          : c
        a.prev = c
        return a
      }, {})
      .str
    }
    return acc
  }, {})

console.log('Formatted result:', result)
.as-console-wrapper {
  max-height: 100% !important;
  top: 0;
}

答案 1 :(得分:0)

  

Array#reduce可以与基于是否存在某些键的值的条件一起使用。如果"A"type

,可以将""用作默认值

let input = [{
  "type": "A"
}, {
  "type": ""
}, {
  "type": ""
}, {
  "type": "B"
}, {
  "type": "C"
}, {
  "type": ""
}, {
  "type": "A"
}, {
  "type": "D"
}, {
  "type": "C"
}];

let output = input.reduce((a, i, index) => {
  let key = i.type || 'A';
  a[key] ? a[key].push(index) : (a[key] = [index]);
  return a;
}, {});
console.log(output);

答案 2 :(得分:0)

另一种实现方法如下:

var d =[{"type":"A"},{"type":""},{"type":""},{"type":"B"},{"type":"C"},{"type":""},{"type":"A"},{"type":"A"},{"type":"D"},{"type":"C"}];
var ranges = {}; 
d.forEach(function(item,key){
	var ind = key;
	var val = item.type;
	while(val == ""){
		ind = ind-1;
		val = d[ind].type;
	}
	if(!ranges[val]){
        ranges[val] = [];
        ranges[val].push(key);
    }
	else{
        var length = ranges[val].length;
		if( d[key-1].type == d[key].type || d[key-1].type == val){
             var splits = ranges[val][length-1].toString().split('-');		
			 ranges[val][length-1] = splits[0] +"-"+key;
        }else{
             ranges[val].push(key);
        }
    }
});
Object.keys(ranges).forEach(function(key){
console.log(key+":"+ranges[key].join(","));
})