给出一个长度相等的数组:
const items = [
'this/is/path1',
'this/is/path2',
'this/is/path3',
'this/is/path4',
'this/is/path5',
'this/is/path6'
];
我想创建一个对象数组,该数组的长度为objnb
。
基于此长度,我将上面的items
分成多个块,然后将第一个索引存储在新的对象属性path
上,并将以下元素存储在other1
,{{1} };其他对象块也一样。
我的解决方案很hacky:
other2
输出正确:
const objnb = 2;
const other1 = true;
const other2 = true;
const outputobjs = items.length / objnb;
const result = items.map((entry, index) => {
let obj = {};
console.log({ entry, index })
if (index % outputobjs === 0) {
obj.path = entry;
obj.others = {};
if (other1) {
obj.others.two = items[index + 1];
}
if (other2) {
obj.others.three = items[index + 2];
}
return obj;
}
return obj;
})
console.log('result: ', result)
但是不幸的是,我得到了我不想要的空对象。 如何以更简洁的方式实现相同目标?
首选结果将不包含空对象。
另一个示例是:
[ { path: 'this/is/path1',
others: { two: 'this/is/path2', three: 'this/is/path3' } },
{},
{},
{ path: 'this/is/path4',
others: { two: 'this/is/path5', three: 'this/is/path6' } },
{},
{} ]
结果是:
const items = [
'this/is/path1',
'this/is/path2',
'this/is/path3',
'this/is/path4'
];
const objnb = 2;
const other1 = true;
const other2 = false;
const outputobjs = items.length / objnb;
const result = items.map((entry, index) => {
let obj = {};
console.log({ entry, index })
if (index % outputobjs === 0) {
obj.path = entry;
obj.others = {};
if (other1) {
obj.others.two = items[index + 1];
}
if (other2) {
obj.others.three = items[index + 2];
}
return obj;
}
return obj;
})
console.log('result: ', result)
新数组中的每个对象都将相似,例如,它们都将具有[ { path: 'this/is/path1', others: { two: 'this/is/path2' } },
{},
{ path: 'this/is/path3', others: { two: 'this/is/path4' } },
{} ]
,并且由于我们将原始数组均匀划分,因此新对象将具有所有相同的属性。例如,如果一个对象具有path
,则新数组中的其余对象都将具有此属性,如果应该具有two
,则它们都将具有该属性。
新对象将如下所示:
three
因此,基本上,通过将原始项数组划分为特定的数(2、3、4等),我们会将其分块为较小的数组,新对象{ path: 'this/is/path1',
others: {
two: 'this/is/path2',
three: 'this/is/path3' // optional; if one object has this, others must have it too.
}
}
将是{{1 }},并且如果此新的分块数组中还有一个项目,则path
将是chunkedArray[0]
,如果还有一个项目,则two
将是chunkedArray[1]
因此,如果我们将其除以2,那么我们将得到:
three
因此,新对象将具有chunkedArray[2]
和const chunkedArray1 = [
'this/is/path1', // path
'this/is/path2', //others.two
'this/is/path3' //others.three
];
const chunkedArray2 = [
'this/is/path4',// path
'this/is/path5',//others.two
'this/is/path6'//others.three
];
;
但是如果将其分为3,我们将得到:
two
所以每个对象只有路径和three
。
每个新的chunkedArray的长度至少为2,这意味着路径和const chunkedArray1 = [
'this/is/path1',// path
'this/is/path2'//others.two
];
const chunkedArray2 = [
'this/is/path3',// path
'this/is/path4'//others.two
];
const chunkedArray3 = [
'this/is/path5',// path
'this/is/path6'//others.two
];
存在于每个新对象中。
一个基本的例子是,如果原始数组是三个,那么我们就不能将其均匀地分成较小的块,所以:
two
如果原始数组为两个长度,则在此处相同:
two
答案 0 :(得分:1)
以下是使用reduce
的一种解决方案。
const items = [
'this/is/path1',
'this/is/path2',
'this/is/path3',
'this/is/path4',
'this/is/path5',
'this/is/path6'
]
function splitItems(data, chunkSize) {
if (chunkSize < 2) return data // or the special value you'd like.
const labels = {
1: 'one',
2: 'two',
3: 'three',
4: 'four'
// ... others
}
return data.reduce((pre, cur, index) => {
if (index % chunkSize === 0) {
/* for old question
pre.push({
path: cur,
others: {}
})*/
let newItem = {
path: cur,
others: {}
}
Array.from(Array(chunkSize-1).keys()).map( itemIndex => {
newItem.others[labels[(itemIndex+1) % chunkSize + 1]] = '' //or other default valu
})
pre.push(newItem)
}
else {
pre[pre.length - 1].others[labels[index % chunkSize + 1]] = items[index]
}
return pre
}, [])
}
console.log('@Test Case 1@', splitItems(items, 2), '@@')
console.log('@Test Case 2@', splitItems(items.slice(0, 2), 2), '@@')
console.log('@Test Case 3@', splitItems(items.slice(0, 4), 2), '@@')
console.log('@Test Case 4@', splitItems(items.slice(0, 5), 3), '@@')
// calc the size first, then exec splitItems
function splitByLength(data, numberOfChunks) {
let chunkSize = Math.round(data.length/3, 0)
return splitItems(data, chunkSize)
}
console.log('@Test Case 5@', splitByLength(items.slice(0, 5), 3), '@@')
答案 1 :(得分:0)
简而言之,您可以循环每3个项目并将其作为对象推送。
const items = [
'this/is/path1',
'this/is/path2',
'this/is/path3',
'this/is/path4',
'this/is/path5',
'this/is/path6'
];
var result = [];
for(var i = 0; i < items.length; i++){
if(i%3==0){
result.push({
path: items[i],
others: {two: items[i+1] || null, three: items[i+2] || null}
})
}
}
console.log(result)
答案 2 :(得分:0)
另一种使用reduce的解决方案,尽管与@sphinx答案有点相似:
const objnb = 3;
const otherKeys = ['two', 'three'];
const items = [
'this/is/path1',
'this/is/path2',
'this/is/path3',
'this/is/path4',
'this/is/path5',
'this/is/path6'
];
const outputobjs = Math.ceil(items.length / objnb);
const ar = items.reduce((memo, item, index) => {
const mod = index % outputobjs
if(mod === 0)
memo.push({path: item, others: {}});
else if(mod <= otherKeys.length)
Object.assign(memo[memo.length - 1].others, {[otherKeys[mod -1]]: item});
return memo;
}, []);
console.log(ar);