繁体   English   中英

如何根据所包含属性的首字母过滤数组?

[英]How can I filter an array based on the first letter of a contained property?

我有以下对象的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;
});

您的代码没有给出预期结果的原因至少有两个:

  • 您使用的索引指向原始数组中的索引。 由于新数组将包含更多元素,因此在新数组上使用该索引进行splice没有任何意义。 最终它将指向错误的位置。

  • 您只需推送prev元素,所以最后一个元素将永远不会被推送到结果数组

我建议使用带有累积值(回调的第一个参数)的reduce来建立最终数组。 为了记住引入的最后一个字母对象,我将把这个累加值与那个字母配对。 因此,我将使用包含两个元素的数组:

  • 最后的数组正在累积
  • 最近添加的字母对象的字母

然后,最终结果将从该数组的第一个元素获取,而忽略第二个值。

我建议不要使用字符代码,而只能使用字符。 它使您免于将代码转换回字符的麻烦。

这是代码:

 var list = [ {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} ]; var newArr = list.reduce(function(collect, cur, index, originalArrray) { var currentChar = cur.name.toUpperCase().substr(0,1); if (currentChar < 'A') currentChar = '#'; if (collect[1] != currentChar) { collect[0].push({isLetter: true, letter: currentChar}); collect[1] = currentChar; } collect[0].push(cur); return collect; }, [[], null])[0]; // output console.log(newArr); 

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

 var names = [{ 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 }]; var newNames = []; for (var i in names) { var char = names[i].name.substring(0, 1); var isNumber = !isNaN(char); var entry = { letter: (isNumber ? '#' : char.toUpperCase()), isLetter: isNumber }; newNames.push(entry); newNames.push(names[i]); } console.log(newNames); 

也许用这种方法可以解决问题

 var list = [{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}]; var listResult = []; list.map(function(item, index) { if(index > 0) { var currentCharcode = item.name.toUpperCase().charCodeAt(0); var previousCharcode = list[index-1].name.toUpperCase().charCodeAt(0); if(previousCharcode != currentCharcode) { listResult.push({isLetter: true, letter: String.fromCharCode(currentCharcode)}); } } else { listResult.push({isLetter: true, letter: String.fromCharCode(currentCharcode)}); } listResult.push(item); }); console.log(JSON.stringify(listResult)); 

我想您也可以通过这样的功能方式进行操作;

 var arr = [{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}], table = arr.reduce((p,c) => {var firstLetter = c.name[0]; isNaN(+firstLetter) ? p[firstLetter] ? p[firstLetter].push(c) : p[firstLetter] = [c] : p["#"] ? p["#"].push(c) : p["#"] = [c]; return p; },{}), result = Object.keys(table).reduce((p,k) => p.concat({letter: k, isLetter: true},table[k]),[]); console.log(result); 

提示:+“ A”返回NaN,但+“ 4”返回4作为数字。 因此, isNaN()是检查类型的非常有用的函数。

这是具有常规功能而不是箭头的版本;

 var arr = [{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}], table = arr.reduce(function(p,c){ var firstLetter = c.name[0]; isNaN(+firstLetter) ? p[firstLetter] ? p[firstLetter].push(c) : p[firstLetter] = [c] : p["#"] ? p["#"].push(c) : p["#"] = [c]; return p; },{}), result = Object.keys(table).reduce(function(p,k){ return p.concat({letter: k, isLetter: true},table[k]); },[]); console.log(result); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM