【问题标题】:How to create an array of all first letters from object properties in another multidimentional array?如何从另一个多维数组中的对象属性创建一个包含所有首字母的数组?
【发布时间】:2016-02-06 10:56:34
【问题描述】:

我有一个包含对象的数组,每个对象都包含一个名为 name 的属性。

现在我想要第二个数组,其中包含第一个数组中每个名称属性的第一个字母。如果第一个字母尚不存在,则应将其保存在名为 header 的属性中。

我只想让一个字母出现一次,因为这个脚本旨在用于一个字母标题列表,每个标题都包含一个以相同字母开头的名称列表。

我创建了一个使用内置 JavaScript“过滤器”方法的函数,该方法应该检查带有第一个字母的值是否已经存在。但由于某种原因,它不起作用。无论我提供什么字母,过滤器总是返回一个空数组。

我一直在试图弄清楚为什么我的脚本没有成功。我非常感谢任何帮助!

var fruit = [{title:"Apple"},{title:"Avocado"},{title:"Banana"},{title:"Cucumber"}];
var sections = [];
function createAlphabetSections(array) {
        for(var i = 0; i < array.length; i++){
            var firstLetter = array[i].title.charAt(0).toUpperCase();
            var section = sections.filter(function (section) { return section.header === firstLetter;});
            if(sections.length === 0){
                sections.push([{header: firstLetter}]);  
            } else if (section.length > 0){
                sections.push([{header: firstLetter}]);
            }
        }
}
createAlphabetSections(fruit);

【问题讨论】:

  • 请提供预期函数输出的示例。
  • 该函数应该返回一个对象数组。每个对象都应该有一个名为 header 的属性,它具有分配给它的第一个数组中每个 title 属性的第一个字母。应删除重复项:[Object { headerTitle="A"}, Object { headerTitle="B"}, Object { headerTitle="C"}]

标签: javascript arrays object filter


【解决方案1】:

首先使用 map 从当前数组构建一个新数组。然后过滤掉所有重复项。

var sections = fruit.map(function (item) {
    // Return the first letter of the title property
    return item.title.substring(0, 1);
}).filter(function (value, index, self) {
    // http://stackoverflow.com/a/14438954/1789518
    return self.indexOf(value) === index;
});

【讨论】:

  • 代码运行良好。我花了一段时间才弄清楚这里发生了什么:return self.indexOf(value) === index; 我知道 self 是数组,indexOf 将返回给定值第一次出现的键。这意味着我们总是在这里检查给定值在该数组中的第一次出现。然后我们比较这个值的索引是否与当前索引相同。如果是,则表示该项目是唯一的,我们返回 true。如果索引不同,则意味着我们找到了重复项并返回 false。 filter 方法只返回返回 true 的项目。
  • 在我的例子中 map() 应该返回一个对象数组,每个对象都包含一个名为 header 的属性。也许我错了,但在这种情况下,我认为我不能在过滤器中使用 indexOf() ,因为我希望将两个对象属性相互比较,而不是两个数组值。有没有办法让 indexOf 方法对对象属性起作用,还是我必须使用不同的方法?
  • 我找到了一个解决方案,可以返回我想要的对象。我在脚本末尾添加了另一个映射,将所有字符串值转换为对象:var sections = fruit.map(function (item) { return item.title.substring(0, 1);}).filter(function (value, index, self) { return self.indexOf(value) === index; }).map(function (item) { return {headerTitle: item} })
【解决方案2】:
var getLetters = function(items) {
    var letters = [];

    items.forEach(function(item) {
        if(letters.indexOf(item.title[0].toUpperCase()) === -1) {
            letters.push(item.title[0].toUpperCase());
        }
    });

    return letters;
};

getLetters([{title:"Apple"},{title:"Avocado"},{title:"Banana"},{title:"Cucumber"}]);

【讨论】:

  • 这个解决方案也很有帮助。非常感谢!
猜你喜欢
  • 2010-11-18
  • 1970-01-01
  • 2019-02-23
  • 1970-01-01
  • 1970-01-01
  • 2019-12-22
  • 1970-01-01
  • 2021-12-26
  • 1970-01-01
相关资源
最近更新 更多