如何在JavaScript中创建一个索引从1开始的数组?

37

默认情况下,每个 JavaScript 数组的索引都从 0 开始。我想创建一个索引从 1 开始的数组。

我知道,这可能非常琐碎... 感谢您的帮助。


17
为什么你想这样做?我问这个问题是因为当你发现自己试图规避编程语言中最基本的特性时,很有可能有更好的方法来实现你想要做的事情。 - Syntactic
5
此外,从0开始的数组索引是一种特性,而不是错误。 - Robusto
1
如果你想向用户显示索引,你可以直接显示 i + 1。你真的应该习惯零索引,因为如果你绕过它,你一生中会遇到很多栅栏帖错误。 - Marie
1
如果你非常想要,那么你可以创建自己的数据结构。例如singlyLinkedList,并修改它的方法。 - user12200634
也许 OP 想要检查索引的值是否存在,以便执行某些操作。您可以这样做,而不是从 1 开始:if(i !== false) - Andres SK
一个从1开始的数组在JS中不被视为数组,而是被视为对象。 - Hybrid web dev
12个回答

31

这并不是一件简单的事情,而是不可能的。你最好能够创建一个使用数字属性从1开始的对象,但那并不是同一件事。

为什么你要从1开始呢?可以选择:

  • 从0开始,并根据需要调整索引;或者

  • 从0开始,只忽略索引0(即仅使用索引1及以上)。


不可能...这真是令人惊讶!好吧,我说这话没什么有用的理由...只是个想法,想从1开始。所以,我想我必须相应地调整我的索引,这不是问题。 只是为了玩味而想从1开始。 - detj
3
现在,8年后,您可以使用Map - xpuu
如何在Javascript中忽略索引0? - josefdev
1
@josefdev - 在那里放一个值,然后永远不要引用它。例如:a = ["ignore me", "this has index 1", "another string, at index 2"]; firstString = a[1]; 然而,这个建议并不是非常有用 - 内置函数如 for (s of a) 不会“知道”你想忽略 a[0] - 完全由你来找到不使用 a[0] 的编码方式;习惯从0开始的数组更加实用。 - ToolmakerSteve

13

一个简单的解决方案是填充第零项:

var map = [null, 'January', 'February', 'March'];
'First month : ' + map[1];


从语义的角度来看,使用一个对象会更好:

var map = {1:'January', 2:'February', 3:'March'};
'First month : ' + map[1];

请注意这些键实际上不是整数,对象键始终为字符串。
此外,我们不能使用点表示法来访问。(MDN - 属性访问器


我会选择第一种解决方案,我认为它较少令人困惑。


12

9
这只创建了一个数组,其第一个值为1。这个问题是关于如何创建一个以索引1为首的数组,这是一件非常不同的事情。 - Matt Korostoff
这个回答是错误的:在对原始数组 someArray 执行 slice 后,它并没有从索引 1 开始,而是仍然从索引 0 开始。 slice() 方法将所选元素作为一个新数组返回,从给定的起始位置选择它们,一直到(不包括)给定的终止位置。此外,如果省略第二个参数,则 slice 返回从一个参数开始的所有元素。slice() 方法不会改变原始数组。 此外,返回的数组已经失去了第一个元素,并且其余元素向左移动了 n 个位置。 - willy wonka
在您的答案中,n 是第一个参数,在第一个示例中为1,在第二个示例中为2。 - willy wonka

3
您可以使用delete来删除第一个元素,操作如下:

let arr = ['a','b','c'];
delete arr[0];

console.log(arr[0]);
console.log(arr[1]);

或者干脆不定义它:

let arr = [,'b','c'];

console.log(arr[0]);
console.log(arr[1]);

如果你想确保始终获取第一个 truthy 元素,而不考虑索引,并且可以使用 ES6,则可以使用以下代码:

arr.find(Boolean)

1
这个问题问的是“如何在JavaScript中创建一个索引从1开始的数组”。接受的答案说“这不是微不足道的,而是不可能的。” 这是真的,并且应该有充分的理解。但是,您可以创建一个数组并“省略设置第一个元素”,在这种情况下它仍将存在(因此接受的答案是正确的),但对于您来说它将被标记为空。
let usernames = ['bob', 'sally', 'frank']
let myArray = [];
let arrayIndex = 1;

usernames.map(username => {
    myArray[arrayIndex] = username;
    arrayIndex++;
})

console.log(myArray);

数组(4)[<1个空槽>,“bob”,“sally”,“frank”]
1:“bob”
2:“sally”
3:“frank”
长度:4

注意长度为“4”。

console.log(myArray[0]);

未定义

使用这个方法,我们有一个优势,就是在数组上使用 Object.keys() 不会返回空的(未定义的)元素。因此,在上面的数组中:

console.log(Object.keys(myArray).length);

3

注意:这可能有点不太正式,使用时请小心。
由于在我们的世界中很少存在零个某物,因此在仅访问预定义索引的情况下,这样做可能会很有用。例如,如果您有一本书的页面,则不存在第0页,因为这毫无意义。如果您总是直接访问一个值,例如:
const currentPage = pages[1];

我认为只要代码表达出意图,这样做就没问题。有人会争辩忽略有效的数组索引是徒劳的,我并不完全反对。然而,当我想获取一本书的第35页时,数组索引却是34,这也徒劳且非常恼人。在使用 map 循环你的(有问题的)数组时,它会忽略你不想要的0索引。
myArray.map((value, index) => {
    console.log(index);
    console.log(value);
})

1
鲍勃
2
莎莉
3
弗兰克

然而,对于一般用途,您应该使用索引0,因此当您循环一些数据并输出内容时,您不会被第一个为空的内容所困扰。


0

好的,根据 @cletus 的说法,你不能这样做,因为它是内置的 JavaScript 功能,但如果你仍然想要那个功能,可以稍微换一种方式。你可以编写自己的基于索引的数组函数(如 reducemapforEach),从 1 开始。这不是一个困难的任务,但请问自己:我为什么需要这个?

Array.prototype.mapWithIndexOne = function(func) {
  const initial = []
  for (let i = 1; i < this.length + 1; i++) {
    initial.push(func(this[i - 1], i))
  }
  return initial
}

const array = ['First', 'Second', 'Third', 'Fourth', 'Fifth']

console.log(array.mapWithIndexOne((element, index) => `${element}-${index}`))
// => ["First-1", "Second-2", "Third-3", "Fourth-4", "Fifth-5"]

Codepen: https://codepen.io/anon/pen/rvbNZR?editors=0012


0

只想指出,在 C 编程语言中,索引也是从第一个元素开始的偏移量。这允许各种偏移量计算,而不必在进行数学运算之前减去 1,只需稍后再加回 1。

如果您想要一个“1”数组,因为索引映射到其他值,那么对于枚举或哈希就是这种情况。


0
使用 Array.map
[,1,2,3].map((v, i) => ++i)

抱歉,我不太确定这是什么意思。看起来在使用“map”之前,您已经有了1索引数组。 - General Grievance

0
如果您在Chrome中打开devTools(F12),并输入以下JavaScript代码:
arr=[,'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
则Google Chrome开发者控制台将显示以下结果:

The result shown by Google Chrome console

请注意,索引从1开始,但这并不意味着arr [0]项不存在:实际上它是空的。事实上,您可以注意到最后一个索引为26,但长度为27,因此有一个数组项未显示。 现在您可以从i = 1开始for循环,但数组长度仍与最后一个索引不同:实际上它是i + 1。 另外,执行arr [0]将得到未定义的结果,就像执行arr [27]一样。
而且,您也可以从i = 1开始循环:

arr=[,'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']

for(i=1; arr[i]!=undefined; i++) {console.log(i + ':' +arr[i])}

有时候知道这个可能会很有用,但是i=0的项仍然存在,只是因为它是空的或未定义而没有显示。即使最后一个数组项的索引是26,长度为27也证明了这一事实。

如果您将其他某些项目设置为空,则会得到类似的结果: enter image description here

空项目表示为没有数字。 但是,如果您将项目设置为未定义,则呈现为未定义而不是空:

enter image description here

当然,如果您像下面这样循环,仍然可以呈现未定义的内容: for(i=0; i<arr.length; i++) {console.log(i +':'+ arr[i])} 那么您将得到以下结果:

enter image description here

从上面的截图中可以看到,i=0的项存在,但i=27的项不存在。

所以回答这个问题: 在javascript中,数组的索引从0开始,而不从其他位置开始。但我们可以观察到一些类似“仿真”的行为,即使它不完全是真实的。

在VBA中,可以在代码模块顶部使用“Option Base 1”声明来将默认下限更改为1,而不是0。但是似乎Javascript目前还没有这种可能性。

还可以使用delete方法获取空/未定义元素 let myarr = ['first','second','third','more elem']; delete myarr[0]; 现在myarr是 [empty,'second','third','more elem']; 并且我之前说的仍然有效。查看Chrome控制台:

enter image description here


-1

首先将此函数添加到您的JavaScript代码中:

var oneArray = function(theArray)
{
    theArray.splice(0,0,null);
    return theArray
}

现在像这样使用它:

var myArray= oneArray(['My', 'name', 'is', 'Ram']);

alert(myArray[1]); << this line show you:   My

请查看实时演示


3
这种方法在许多数组方法中都行不通。例如,Array.from(myArray.keys())返回[0, 1, 2, 3, 4]而不是[1, 2, 3, 4, 5] - Michał Perłakowski
1
@Gothdo,我认为你错了!因为这个结果>> [0, 1, 2, 3, 4]对于@detj(提问者)来说没有任何意外的值。他只需要在n>=1时使用([0, 1, 2, 3, 4])[n]。所以这个数组对他来说总是有正确的结果。 - Ramin Bateni

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接