对象的JavaScript数组:如果一个值接一个值相同,则分组



如果数组项相同,我需要对它们进行分组。但前提是他们一个接着一个。

之前或之后没有相同值的单个项目应被忽略。

示例:

const array = [
{country : 'usa', continent: 'north america'},
{country : 'germany', continent: 'europe'},  
{country : 'france', continent: 'europe'},
{country : 'india', continent: 'asia'},
{country : 'netherlands', continent: 'europe'},
]

结果应该是:

[
{country : 'usa', continent: 'north america'},
[
{country : 'germany', continent: 'europe'},  
{country : 'france', continent: 'europe'} 
],
{country : 'india', continent: 'asia'},
{country : 'netherlands', continent: 'europe'},
]
]

这个解决方案也会起作用:

[
{country : 'usa', continent: 'north america'},
{grouped: 'continent', countries: [
{country : 'germany', continent: 'europe'},  
{country : 'france', continent: 'europe'} 
]
},
{country : 'india', continent: 'asia'},
{country : 'netherlands', continent: 'europe'},
]
]

一种方法是循环遍历数组并存储最后一个continent值,如果它与前一项相同,则将前一项移动到数组中并将当前项添加到其中。

Array.reduce()可用于此任务:

const array = [
{country : 'usa', continent: 'north america'},
{country : 'germany', continent: 'europe'},  
{country : 'france', continent: 'europe'},
{country : 'india', continent: 'asia'},
{country : 'netherlands', continent: 'europe'},
];
const newArray = array.reduce((map, item) =>
{
let prevItem = map[map.length-1]; //get prevous item
// is previous continent matches current?
if (prevItem && (prevItem.continent || (prevItem[0] && prevItem[0].continent)) === item.continent)
{
if (prevItem.continent) //if it's not an array, convert it into one
{
prevItem = [prevItem]; //convert prevous item into array
map.splice(-1, 1, prevItem); //replace prevous item with new array'ed item
}
prevItem[prevItem.length] = item; //append current item to the array
}
else
map[map.length] = item;
return map;
}, [] /* "map" array */);
console.log(newArray);

这样就可以了。

有一个空白的新数组,用于存储答案。

该算法只是在现有数组中迭代,保存一个临时的匹配数组。当下一个条目与上一个条目不匹配时,它会将该临时数组添加到新数组中。

const array = [{
country: 'usa',
continent: 'north america'
},
{
country: 'germany',
continent: 'europe'
},
{
country: 'france',
continent: 'europe'
},
{
country: 'india',
continent: 'asia'
},
{
country: 'netherlands',
continent: 'europe'
},
]
const newArray = []
var tempArray = []
var previousContinent = ""
array.forEach(item => {
if (item.continent === previousContinent) {
tempArray.push(item)
} else {
// Delete this first check if you don't mind every entry being an array
if (tempArray.length === 1) {
newArray.push(tempArray[0])
} else if (tempArray.length > 0) {
newArray.push(tempArray)
}
previousContinent = item.continent
tempArray = [item]
}
})
if (tempArray.length === 1) {
newArray.push(tempArray[0])
} else if (tempArray.length > 0) {
newArray.push(tempArray)
}
console.log(newArray)

由于您有条件将两个国家分组在同一个大陆中,它们应该是相邻的兄弟国家,因此产生该结果并只访问输入数组一次的最快方法是跟踪前一个大陆,并在下一个输入国家断链时填充一个国家队列以同时推送输出。

此演示将在控制台上输出如前所述精心制作的结果数组:

const array = [
{country : 'usa', continent: 'north america'},
{country : 'germany', continent: 'europe'},  
{country : 'france', continent: 'europe'},
{country : 'india', continent: 'asia'},
{country : 'netherlands', continent: 'europe'},
];
function flushQueue(queue, destination, useWrapper = false){
//if the queue has more than one country
if(queue.length > 1){
//if useWrapper was passed to the function as true
if (useWrapper){
//overwrites queue with the new wrapper object
queue = {
//the continent property is picked by the first item in the queue
//there's no need to check any other coming next, because anyway 
//they would be sharing all the same value. The first item will
//exist for sure because this branch runs if the length>1.
grouped : queue[0].continent,
countries : queue
};
}
//adds the whole array queue to the result
destination.push(queue);
//otherwise if there's one country only
}else{
//adds the single country to the result
destination.push(queue[0]);
}
}
function groupCountries(array, useWrapper = false){
let result = [];
let prevContinent;
let queue = [];
array.forEach((o, i)=>{
//if this isn't the first element and 
//the previous continent is different from the current one
if(typeof prevContinent !== "undefined" && prevContinent != o.continent){
//flushes the queue of grouped countries to the result array
flushQueue(queue, result, useWrapper);
//resets the queue
queue = [];
}
//adds the current country to the queue before it gets flushed in groups
queue.push(o);
//refresh prevContinent with the current value before turning to the next
prevContinent = o.continent;
});
//flush the remaining elements in the queue, before..
flushQueue(queue, result, useWrapper);

//..returning the result
return result;
}
let result;
//first fashion
result = groupCountries(array);
console.log(result);
//second fashion
result = groupCountries(array, true);
console.log(result);

最新更新