Javascript 如何根据所包含属性的第一个字母筛选数组?

Javascript 如何根据所包含属性的第一个字母筛选数组?,javascript,arrays,reduce,aramex,Javascript,Arrays,Reduce,Aramex,我有以下JavaScript对象数组: [{name: '4 Arn', isLetter: false}, {name: 'Abax', isLetter: false}, {name: 'Aramex', isLetter: false}, {name: 'Booking', isLetter: false}, {name: 'Dangerous', isLetter: false}, {name: 'Manali', isLetter: false}] 在上面的数组中,我想检查每个项的n

我有以下JavaScript对象数组:

[{name: '4 Arn', isLetter: false},
{name: 'Abax', isLetter: false},
{name: 'Aramex', isLetter: false},
{name: 'Booking', isLetter: false},
{name: 'Dangerous', isLetter: false},
{name: 'Manali', isLetter: false}]
在上面的数组中,我想检查每个项的name属性的第一个字母。如果匹配,我想在对象之前添加一个新对象,如以下示例所示:

[{letter: "#", isLetter: true},       // new object 
{name: '4 Arn', isLetter: false},
{letter: "A", isLetter: true},        // new Object
{name: 'Abax', isLetter: false},
{name: 'Aramex', isLetter: false},
{letter: "B", isLetter: true},        // new object
{name: 'Booking', isLetter: false},
{letter: "D", isLetter: true},        // new object
{name: 'Dangerous', isLetter: false},
{letter: "M", isLetter: true},        // new object
{name: 'Manali', isLetter: false}]
我尝试了reduce函数,但我不明白为什么它会给我错误的结果:

var newArr = [];
list.reduce(function(prev, cur, index, originalArrray) {
    var previousCharcode = prev.name.toUpperCase().charCodeAt(0);
    currentCharCode = cur.name.toUpperCase().charCodeAt(0);

    newArr.push(prev);
    if(previousCharcode != currentCharCode) {
        newArr.splice(index, 0, {isLetter: true, letter: String.fromCharCode(currentCharCode)});
    }
    return cur;
});

检查此解决方案。迭代数组并将其附加到新数组

变量名称=[{ 名称:“4 Arn”, 伊斯兰特:错 }, { 名称:“Abax”, 伊斯兰特:错 }, { 名称:“Aramex”, 伊斯兰特:错 }, { 名称:'预订', 伊斯兰特:错 }, { 名称:“危险”, 伊斯兰特:错 }, { 姓名:'玛纳利', 伊斯兰特:错 }]; var newNames=[]; 对于名称中的var i{ var char=names[i].name.substring0,1; 变量isNumber=!isNaNchar; 变量项={ 字母:isNumber?:char.toUpperCase, 伊斯兰特:伊斯兰特号码 }; newNames.pushentry; newNames.pushnames[i]; }
console.lognewNames 也许用这种方法你可以解决这个问题

var list=[{name:'4 Arn',isLetter:false}, {name:'Abax',isleter:false}, {name:'Aramex',isLetter:false}, {name:'Booking',isleter:false}, {name:'危险',isleter:false}, {name:'Manali',isLetter:false}]; var listResult=[]; list.mapfunctionitem,索引{ ifindex>0{ var currentCharcode=item.name.toUpperCase.charCodeAt0; var previousCharcode=list[index-1]。name.toUpperCase.charCodeAt0; ifpreviousCharcode!=当前CharCode{ push{isLetter:true,letter:String.fromCharCodecurrentCharcode}; } }否则{ push{isLetter:true,letter:String.fromCharCodecurrentCharcode}; } listResult.pushitem; };
console.logJSON.stringifylistResult 我想你也可以用这样的功能方式来做

var arr=[{name:'4 Arn',isLetter:false}, {name:'Abax',isleter:false}, {name:'Aramex',isLetter:false}, {name:'Booking',isleter:false}, {name:'危险',isleter:false}, {name:'Manali',isLetter:false}], table=arr.reducep,c=>{var firstLetter=c.name[0]; isNaN+firstLetter?p[firstLetter]?p[firstLetter].pushc :p[第一个字母]=[c] :p[]?p[].pushc :p[]=[c]; 返回p; },{}, result=Object.keystable.reducep,k=>p.concat{letter:k,isLetter:true},table[k],];
console.logresult 代码未给出预期结果的原因至少有两个:

使用的索引指向原始数组中的索引。由于新阵列将有更多的元素,因此将该索引用于新阵列上的拼接是没有意义的。它最终会指向错误的地方

只推送上一个元素,因此最后一个元素永远不会推送到结果数组

我建议在回调函数的第一个参数中使用reduce,该参数将构建最终数组。为了记住引入的最后一个字母对象,我将把这个累积值与该字母配对。因此,我将使用包含两个元素的数组:

正在累积的最终数组 最近添加的字母对象的字母 然后从该数组的第一个元素获取最终结果,忽略第二个值

我建议不要使用字符代码,而只使用字符。它可以避免将代码转换回字符

代码如下:

变量列表=[ {name:'4 Arn',isleter:false}, {name:'Abax',isleter:false}, {name:'Aramex',isLetter:false}, {name:'Booking',isleter:false}, {name:'危险',isleter:false}, {name:'Manali',isLetter:false} ]; var newArr=list.reducefunctioncollect、cur、index、originalarray{ var currentChar=cur.name.toUpperCase.substr0,1; 如果currentChar<'A'currentChar=; 如果收集[1]!=currentChar{ 收集[0]。推送{isLetter:true,字母:currentChar}; collect[1]=currentChar; } 收集[0]。pushcur; 回款到付; },[],null][0]; //输出
console.lognewArr;我能问一下你为什么要选择那种结构吗?这真的不是很好的设计。最好将具有相同起始字母的节点放置为字母节点的子节点,以便在顶层仅具有字母节点,而在第二层仅具有原始节点。这适用于离子列表视图。我希望每个新的第一个字母仅插入一次新对象,而不是每次。