我有一个像这样的对象数组(按类型排序,相同类型的对象是相同的):
[
{ "type":"A", "height":50, "width":80 },
{ "type":"A", "height":50, "width":80 },
{ "type":"B", "height":20, "width":100 },
{ "type":"B", "height":20, "width":100 },
{ "type":"C", "height":90, "width":10 }
]
我希望将所有这些对象放在一个数组中,该数组通过交替使用每种类型的对象来排序:
[
{ "type":"A", "height":50, "width":80 },
{ "type":"B", "height":20, "width":100 },
{ "type":"C", "height":90, "width":10 },
{ "type":"A", "height":50, "width":80 },
{ "type":"B", "height":20, "width":100 }
]
答案 0 :(得分:2)
您可以采用Map
并进行迭代,直到按正确的顺序处理所有项目。
var array = [{ type: "A", height: 50, width: 80 }, { type: "A", height: 50, width: 80 }, { type: "B", height: 20, width: 100 }, { type: "B", height: 20, width: 100 }, { type: "C", height: 90, width: 10 }],
order = ['A', 'B', 'C'],
types = new Map(order.map(k => [k, []])),
result = [];
array.forEach(o => types.get(o.type).push(o));
while (types.size) {
types.forEach((a, k) => (result.push(a.shift()), a.length || types.delete(k)));
}
console.log(result);

.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:0)
这是我的尝试。它不是最有效的,但只要输入不是太大就应该很好。
它假定类型将始终是一个字符串,但它不假设它们将始终是A,B和C.它循环输入数据以确定类型并将匹配类型一起收集为“分区”。一旦完成它就会循环遍历每个分区的类型转移条目,直到它完成为止。如果分区具有不同数量的条目,则没有问题,但是会浪费时间来移动不存在的对象。
您提到每种类型的对象都是相同的,但我没有考虑到这些细节。如果“相同”是指“同一个对象”(即obj1 === obj2
),那么您可以利用它来跟踪计数而不是创建所有这些分区数组。
var input = [
{ "type":"A", "height":50, "width":80 },
{ "type":"A", "height":50, "width":80 },
{ "type":"B", "height":20, "width":100 },
{ "type":"B", "height":20, "width":100 },
{ "type":"C", "height":90, "width":10 }
];
var types = [];
var partitions = {};
input.forEach(function(row) {
var type = row.type;
if (partitions[type]) {
partitions[type].push(row);
}
else {
partitions[type] = [row];
types.push(type);
}
});
var output = [];
while (output.length < input.length) {
types.forEach(function(type) {
var next = partitions[type].shift();
if (next) {
output.push(next);
}
});
}
console.log(output);
答案 2 :(得分:0)
在ES6中写了一小段。
应该相当容易const getAlternate = (ar) => {
const types = [];
const objects = {};
const typeCounts = {};
let totalCount = 0;
ar.forEach((object) => {
if(!types.includes(object.type)) {
types.push(object.type);
objects[object.type] = object;
typeCounts[object.type] = 1;
} else {
typeCounts[object.type]++;
}
totalCount++;
});
/**
* at this point, the state variables will look like this:
* types ['A', 'B', 'C']
* objects { A: { type: 'A', height: 50, width: 80 },
* B: { type: 'B', height: 20, width: 100 },
* C: { type: 'C', height: 90, width: 10 } }
* typeCounts { A: 2, B: 2, C: 1 }
* totalCount 5
*
* now we can use this data to get the alternation!
*/
const newAr = [];
let typeIndex = 0;
while(totalCount > 0) {
totalCount--;
let type = types[typeIndex];
newAr.push(objects[type]);
typeCounts[type]--;
if(typeCounts[type] <= 0) {
types.splice(typeIndex, 1);
typeIndex--;
delete objects[type];
delete typeCounts[type];
}
typeIndex = (typeIndex + 1) % types.length;
}
return newAr
}
我做的第一件事是设置一些状态,以便以后更容易迭代这些类型,包括每种类型的列表,每种类型的对象的副本,以及每种类型的计数
从那里,我宣布一个新的数组,只需使用模数跟随交替,删除我不再需要的所有内容
// here we invoke the function
console.log(getAlternate([
{ "type":"A", "height":50, "width":80 },
{ "type":"A", "height":50, "width":80 },
{ "type":"B", "height":20, "width":100 },
{ "type":"B", "height":20, "width":100 },
{ "type":"C", "height":90, "width":10 }
]));
// and, as expected, we get
[
{"type":"A","height":50,"width":80},
{"type":"B","height":20,"width":100},
{"type":"C","height":90,"width":10},
{"type":"A","height":50,"width":80},
{"type":"B","height":20,"width":100}
]
答案 3 :(得分:0)
试试这个(评论中的解释)
var inputArr = [
{ "type":"A", "height":50, "width":80 },
{ "type":"A", "height":50, "width":80 },
{ "type":"B", "height":20, "width":100 },
{ "type":"B", "height":20, "width":100 },
{ "type":"C", "height":90, "width":10 }
];
//create an index by type
var typeMap = {};
inputArr.forEach( function( item ){
typeMap[ item.type ] = typeMap[ item.type ] || [];
typeMap[ item.type ].push( item );
});
//get sorted type-list
var sortedKeyList = Object.keys( typeMap ); //assuming that keys are always going to be uppercase strings
var output = [];
var noMoreItems = false;
//iterate till there is nothing to iterate
while( !noMoreItems )
{
//add the top item of every key of the map
sortedKeyList.forEach( function( key ){
var arr = typeMap[ key ];
output = output.concat(arr.splice(0,1));
typeMap[ key ] = arr;
});
//remove the empty array keys in the map
sortedKeyList = sortedKeyList.filter( function( key ){
return typeMap[ key ].length > 0;
});
noMoreItems = ( output.length == inputArr.length );
}
console.log( output );
答案 4 :(得分:0)
因此,既然你有订购的物品,那么你也可以这样做;
function braide(a){
// get the chunks ie [a,a,a,a,a,b,b,b,c,c,d] -> [[a,a,a,a,a],[b,b,b],[c,c],[d]]
var chunks = a.reduce((r,o,i,a) => a[i+1] && o.type !== a[i+1].type ? (r[r.length-1].push(o),r.push([]),r)
: (r[r.length-1].push(o),r),[[]]);
// find the longest chunk by appending items from every chunk at the same index position
return chunks.reduce((p,c) => p.length > c.length ? p : c)
.reduce((r,_,i) => (chunks.forEach(c => c[i] && r.push(c[i])),r), []);
}
var data = [{"type":"A","height":50,"width":80},{"type":"A","height":50,"width":80},{"type":"A","height":50,"width":80},{"type":"A","height":50,"width":80},{"type":"A","height":50,"width":80},{"type":"B","height":20,"width":100},{"type":"B","height":20,"width":100},{"type":"B","height":20,"width":100},{"type":"C","height":90,"width":10},{"type":"C","height":90,"width":10},{"type":"D","height":30,"width":70}];
console.log(braide(data));