[英]Node - Access last index of multidimensional arrays
I have a question that I believe is straightforward, but I've seen conflicting answers on.我有一个我认为很简单的问题,但我看到了相互矛盾的答案。
Let's say I have the following data structure:假设我有以下数据结构:
const data = [
...,
{
someKey: [
...,
{
someDeepKey: [
...,
'two'
],
}
]
}
]
So accessing the first index of all of the following would look like this:因此访问以下所有内容的第一个索引将如下所示:
data[0].someKey[0].someDeepKey[0]
But if I wanted to find the LAST index of all of these, I haven't found a clean method.但是如果我想找到所有这些的最后一个索引,我还没有找到一个干净的方法。 I have seen some people recommend extending the Array prototype itself, which I feel is a bad idea.
我看到有人建议扩展 Array 原型本身,我觉得这是个坏主意。
The only other "clean" solution I can think of is to chain down variables to make it semi readable.我能想到的唯一其他“干净”解决方案是链接变量以使其半可读。
let someKey = data[data.length - 1].someKey
let someDeepKey = someKey[someKey.length - 1].someDeepKey
let someDeepKeyValue = someDeepKey[someDeepKey.length - 1]
Can anybody suggest a cleaner way to do this?有人可以建议一种更清洁的方法吗? I believe Python supports something neat such as:
我相信 Python 支持一些简洁的东西,例如:
data[-1].someKey[-1].someDeepKey[-1]
and I was wondering if there is anything similar in JS.我想知道 JS 中是否有类似的东西。
I did happen to stumble upon this.我确实偶然发现了这一点。 It appears to do what I want without mutating the original array, much cleaner than doing the whole
.length - 1
chain:它似乎在不改变原始数组的情况下做我想做的事,比做整个
.length - 1
链要干净得多:
let data = [
{
someKey: [
{
someOtherKey: [
'Fake',
'Name'
]
}
]
}
];
let name = data.slice(-1).pop()
.someKey.slice(-1).pop()
.someOtherKey.slice(-1).pop();
console.log(name) // 'Name'
console.log(data) // Original data
Unsure how performant it is, but its certainly at least a lot more readable and it grabs the end values needed.不确定它的性能如何,但它肯定至少更具可读性,并且可以获取所需的最终值。
Probably a performance nightmare since its making so many copies in memory, but when we're just dealing with smaller datasets, I think this fits the bill to snag accurate values in deeply nested arrays without mutating anything.可能是性能噩梦,因为它在 memory 中制作了如此多的副本,但是当我们只处理较小的数据集时,我认为这符合在深度嵌套的 arrays 中获取准确值而不改变任何内容的要求。
Ran some evaluations.跑了一些评价。 Here are some basic tests here:
这里有一些基本的测试:
// Scaffold a dataset let dataSet = []; for (let i = 0; i < 100; i++) { let someObj = { someKey: [] } for (let j = 0; j < 100; j++) { let someOtherObj = { someOtherKey: [] } for (let k = 0; k < 1000; k++) { someOtherObj.someOtherKey.push(k) } someObj.someKey.push(someOtherObj) } dataSet.push(someObj) } const slicePop = (data) => { // Slice Pop let start = window.performance.now(); let name = data.slice(-1).pop().someKey.slice(-1).pop().someOtherKey.slice(-1).pop(); let end = window.performance.now(); let time = end - start; return time } const spreadPop = (data) => { // Spread Pop let start = window.performance.now(); let name = [...[...[...data ].pop().someKey].pop().someOtherKey].pop() let end = window.performance.now(); let time = end - start; return time } const lastMethod = (data) => { // Function let start = window.performance.now(); const last = (arr) => arr[arr.length - 1] let name = last(last(last(data).someKey).someOtherKey) let end = window.performance.now(); let time = end - start; return time } const variables = (data) => { let start = window.performance.now(); let someKey = data[data.length - 1].someKey let someOtherKey = someKey[someKey.length - 1].someOtherKey let name = someOtherKey[someOtherKey.length - 1] let end = window.performance.now(); let time = end - start; return time } const lastDeep = (arr) => { let start = window.performance.now(); let name = ['someKey', 'someOtherKey', ''].reduce( (last, cur) => ( (res = last[last.length - 1]), res[cur]? res[cur]: undefined ),arr) let end = window.performance.now(); let time = end - start; return time } let slicePopTimes = []; let spreadPopTimes = []; let lastMethodTimes = []; let variablesTimes = []; let reduceTimes = []; for (let i = 0; i < 100; i++) { slicePopTimes.push(slicePop(dataSet)) } for (let i = 0; i < 100; i++) { spreadPopTimes.push(spreadPop(dataSet)) } for (let i = 0; i < 100; i++) { lastMethodTimes.push(lastMethod(dataSet)) } for (let i = 0; i < 100; i++) { variablesTimes.push(variables(dataSet)) } for (let i = 0; i < 100; i++) { reduceTimes.push(lastDeep(dataSet)) } const getAvg = (arr) => { let total = arr.reduce((acc, i) => { acc += i return acc }, 0); return ((total / arr.length) * 1000) } let results = { slicePopTime: getAvg(slicePopTimes), spreadPopTime: getAvg(spreadPopTimes), lastMethodTime: getAvg(lastMethodTimes), variablesTime: getAvg(variablesTimes), reduceTime: getAvg(reduceTimes) } console.log('RESULTS', results)
Here small util using reduce
, will be handy and works for any level of nesting.这里使用
reduce
的小工具会很方便,适用于任何级别的嵌套。
const data = [ { someKey: [ { someDeepKey: ["one"], }, ], }, { someKey: [ { someDeepKey: ["one", "two"], }, ], }, ]; const lastDeep = ["someKey", "someDeepKey", ""].reduce( (last, cur) => ((res = last[last.length - 1]), res[cur]?? res), data ); console.log(lastDeep);
you can following this code您可以按照此代码
let x = [...[...[ ...data ].pop().someKey].pop().someDeepKey].pop()
Define a function named last to get last element of an array and use it like this last(last(last(data).someKey).someDeepKey)
.定义一个名为 last 的 function 以获取数组的最后一个元素并像这样使用它
last(last(last(data).someKey).someDeepKey)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.