简体   繁体   English

节点 - 访问多维 arrays 的最后一个索引

[英]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.

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