在JavaScript中如何返回数组中的正确位置?

huangapple go评论69阅读模式
英文:

How to return the correct position in an array in Javascript?

问题

I understand your request. Here's the translation of the code section you provided:

var widestPasture = function (landscape) {
  // Implement your code below
  let array = landscape.split("-");
  let greatest;
  let tillGreatest = 0;
  let endIndex;
  let answer = [];

  for (let i = 0; i < array.length; i++) {
    if (array[i + 1] !== undefined) {
      greatest = array[i].length;
    }
  }
  
  for (let i = 0; i < array.length; i++) {
    if (array[i].length < greatest) {
      tillGreatest += array[i].length;
    }
  }
  
  let startIndex = tillGreatest += 1;
  
  tillGreatest += 2;
  
  endIndex = tillGreatest + greatest -1;

  answer = [greatest, tillGreatest, endIndex];
  
  return answer;
};

console.log(widestPasture("_-___-__-____-______-_"));
// -> [6, 14, 19]
console.log(widestPasture("_-___-__-___-"));
// -> [3, 9, 11]

If you have any specific questions about the code or need further assistance, please feel free to ask.

英文:

I need to make a function so that it will return the starting and ending index of the widest pasture as well as the width.

It needs to return an array in this particular order.

[length, starting_index, ending_index]

As an example, for &quot;_-___-__-____-______-_&quot;, the return value should be [6, 14, 19].

If there are multiple pastures that have the same length, return the position of the pasture towards the end of the array.

As an example, for &quot;_-___-__-___-&quot;, the return value should be [3, 9, 11].

If the widest pasture length is 0, such as &quot;---&quot;, return 0 for all the values [0, 0, 0].

var widestPasture = function (landscape) {
  // Implement your code below
  let array = landscape.split(&quot;-&quot;);
  let greatest;
  let tillGreatest = 0;
  let endIndex;
  let answer = [];

  for (let i = 0; i &lt; array.length; i++) {
    if (array[i + 1] !== undefined) {
      greatest = array[i].length;
    }
  }
  
  for (let i = 0; i &lt; array.length; i++) {
    if (array[i].length &lt; greatest) {
      tillGreatest += array[i].length;
    }
  }
  
  let startIndex = tillGreatest += 1;
  
  tillGreatest += 2;
  
  endIndex = tillGreatest + greatest -1;

  answer = [greatest, tillGreatest, endIndex];
  
  return answer;
};

console.log(widestPasture(&quot;_-___-__-____-______-_&quot;));
// -&gt; [6, 14, 19]
console.log(widestPasture(&quot;_-___-__-___-&quot;));
// -&gt; [3, 9, 11]

The issue I'm running into is figuring out how to output the [3, 9, 11]. Currently the second output is [3, 6, 8]. It feels like the solution is something simple right in my face but I can't grasp it and all my other attempts have resulted is breaking the currently working code.

Is my only option rewriting from the beginning?

答案1

得分: 2

首先的问题是变量 greatest 被设置为倒数第二个分区,而没有比较哪个分区最长。即使第一个分区是最长的,greatest 仍会被下一个数组的长度覆盖,即使它更短。

其次,tillGreatest 变量获取的是比最长分区更短的数组的长度总和。但这也会包括在最长分区之后的数组的长度。

另一个问题是由于分割,你失去了起始索引的追踪。你尝试用 += 1+= 2 来解决这个问题,但这不够通用。老实说,分割成分区比必要的情况更复杂。

我建议不要进行分割,而是遍历 landscape 字符串的每个字符,并跟踪 当前 连续 _ 系列的起始索引,并推导出它的长度。然后,每当你获得比之前注册的长度更长的长度时,你可以更新答案数组。

这是代码的调整:

var widestPasture = function (landscape) {
    let answer = [0, 0, 0];
    for (let i = 0, start = 0; i < landscape.length; i++) {
        if (landscape[i] != "_") {
            start = i + 1;
        } else if (i + 1 - start >= answer[0]) {
            answer = [i + 1 - start, start, i];
        }
    }
    return answer;
};

console.log(widestPasture("_-___-__-____-______-_"));
// -> [6, 14, 19]
console.log(widestPasture("_-___-__-___-"));
// -> [3, 9, 11]
英文:

The first problem is that the variable greatest is set to the one-but-last partition without comparing which partition is the longest. Even if the first partition would be the longest, greatest will still be overwritten with the length of a next array -- even when it is shorter.

Secondly, the tillGreatest variable gets the sum of the lengths of arrays that are shorter than the greatest. But this will also include lengths of arrays that come after the greatest.

Another issue is that you lose track of the starting indices because of the split. You try to overcome this with += 1 and += 2, but this is not generic enough. Honestly, the split into partitions made this harder than necessary.

I would suggest not to do the split, but just visit each character of the landscape string and keep track of the starting index of the current series of _, and derive its length. Then you can update the answer array whenever you get a length that is greater than what was registered before.

Here is how that looks:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

var widestPasture = function (landscape) {
    let answer = [0, 0, 0];
    for (let i = 0, start = 0; i &lt; landscape.length; i++) {
        if (landscape[i] != &quot;_&quot;) {
            start = i + 1;
        } else if (i + 1 - start &gt;= answer[0]) {
            answer = [i + 1 - start, start, i];
        }
    }
    return answer;
};

console.log(widestPasture(&quot;_-___-__-____-______-_&quot;));
// -&gt; [6, 14, 19]
console.log(widestPasture(&quot;_-___-__-___-&quot;));
// -&gt; [3, 9, 11]

<!-- end snippet -->

答案2

得分: 1

以下是您要翻译的代码部分:

var widestPasture = function (landscape) {
  let array = landscape.split("-");
  let longest = Math.max(...(array.map(el => el.length)));
  let pos = array.lastIndexOf("_".repeat(longest));
  //reconstruct
  let c = 0, firstIndex = 0;
  while (c < pos) {
    firstIndex += array[c].length + 1;
    c++;
  }
  let answer = [longest, firstIndex, firstIndex + longest - 1];
  return answer;
};

console.log(widestPasture("_-___-__-____-______-_"));
// -> [6, 14, 19]
console.log(widestPasture("_-___-__-___-"));
// -> [3, 9, 11]

请注意,代码中的HTML注释(<!-- begin snippet: js hide: false console: true babel: false --><!-- end snippet -->)未进行翻译,因为它们不包含可翻译的文本。

英文:

I was going to type Trincots explanation regarding the greatest variable, so I won't repeat that here, and their solution is great. Here's an alternative solution so you can see different ways of getting to it

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

var widestPasture = function (landscape) {
  let array = landscape.split(&quot;-&quot;);
  let longest = Math.max(...(array.map(el =&gt; el.length)));
  let pos = array.lastIndexOf(&quot;_&quot;.repeat(longest));
  //reconstruct
  let c =0, firstIndex=0;
  while (c&lt;pos) {
   firstIndex += array[c].length +1;
   c++;
   }
  let answer = [longest, firstIndex, firstIndex+longest-1];
  return answer;
};

console.log(widestPasture(&quot;_-___-__-____-______-_&quot;));
// -&gt; [6, 14, 19]
console.log(widestPasture(&quot;_-___-__-___-&quot;));
// -&gt; [3, 9, 11]

<!-- end snippet -->

答案3

得分: 1

使用matchAll是一个可行的方法,它将匹配这个简单的正则表达式... /_+/g... 一个下划线字符的序列(全局)。结果数组包含匹配的项,其中每个项都包括匹配本身(下划线序列)和例如index属性,该属性指示匹配的起始位置。

通过按每个项目的匹配长度按升序对匹配项数组进行sort,将显示OP感兴趣的匹配结果作为排序数组的最后一项。从这个特定项中,可以创建/组装OP正在寻找的结果数组。

英文:

A feasible approach utilizes matchAll which is going to match this simple regex ... /_+/g ... a sequence of underscore characters (globally).

The result array contains matching items where each item features the match itself (the underscore sequence) and e.g. the index property which indicates the match's starting position.

sorting the array of matching items, by each item's match length in an ascending order, will feature the OP's matching result of interest as the sorted array's last item. From this very item one can create/assemble the result array which the OP is looking for.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function getLastValidMatchingPastureData(value) {
  const lastValidPastureMatch = [...String(value).matchAll(/_+/g)]
    // sort each matching pasture data item ascending by `length`.
    .sort(([a], [b]) =&gt; a.length - b.length)
    // access/get the last matching item (the last longest item).
    .at(-1);

  return [ // assemble the data of OP&#39;s interest.
    lastValidPastureMatch[0].length,
    lastValidPastureMatch.index,
    lastValidPastureMatch.index + lastValidPastureMatch[0].length - 1,
  ];
}

console.log( // [3, 9, 11]
  &#39;&quot;_-___-__-___-&quot; ... &#39;,
  getLastValidMatchingPastureData(&quot;_-___-__-___-&quot;),
);
console.log( // [6, 14, 19]
  &#39;&quot;_-___-__-____-______-_&quot; ... &#39;,
  getLastValidMatchingPastureData(&quot;_-___-__-____-______-_&quot;),
);
console.log( // [6, 21, 26]
  &#39;&quot;_-___-__-______-____-______-_&quot; ... &#39;,
  getLastValidMatchingPastureData(&quot;_-___-__-______-____-______-_&quot;),
);

<!-- language: lang-css -->

.as-console-wrapper { min-height: 100%!important; top: 0; }

<!-- end snippet -->

答案4

得分: 0

以下是翻译好的内容:

您可以在下面找到一个简单的解决方案,它循环遍历输入字符,找到牧场,并每当找到比迄今为止最佳的牧场更好的牧场时,它将成为新的迄今为止最佳的牧场。您可以在下面的代码中找到详细的解释。

function widestPasture(input) {
    //在开始时,我们还没有解决方案,所以默认将bestSofar设置为undefined
    let bestSofar = undefined;
    //lastStartIndex为负数意味着我们目前不在牧场内
    let lastStartIndex = -1;
    //我们循环字符串的索引
    for (let i = 0; i < input.length; i++) {
        //我们检查当前字符是否在牧场外
        if (input[i] !== '_') {
            //如果是的话,并且我们之前在牧场内,那么我们找到了当前牧场的结束位置,即i - 1的前一个索引
            if (lastStartIndex >= 0) {
                //我们创建一个解决方案数组,以便与迄今为止的最佳解决方案进行比较
                let currentPasture = [i - lastStartIndex, lastStartIndex, i - 1];
                //如果我们之前没有最佳解决方案,或者迄今为止的最佳解决方案不严格比我们当前的解决方案差,那么我们将bestSofar替换为currentPasture
                if ((!bestSofar) || (bestSofar[0] <= currentPasture[0])) bestSofar = currentPasture;
                //因为我们离开了牧场,所以我们用负值标记lastStartIndex,以便我们知道我们不在牧场内
                lastStartIndex = -1;
            }
        }
        //这里的else意味着字符是'_',所以我们在牧场内
        else if (lastStartIndex < 0) lastStartIndex = i;
    }
    //循环结束后,我们检查是否在最后一个字符处在牧场内,以应对边界情况
    if (lastStartIndex >= 0) {
        //我们创建currentPasture数组
        let currentPasture = [input.length - lastStartIndex, lastStartIndex, input.length - 1];
        //并将其与迄今为止的最佳解决方案进行比较,如果更好,它将成为新的最佳解决方案
        if ((!bestSofar) || (bestSofar[0] <= currentPasture[0])) bestSofar = currentPasture;
    }
    return bestSofar;
}
console.log(widestPasture("_-___-__-____-______-_"));
// -> [6, 14, 19]
console.log(widestPasture("_-___-__-___-"));
// -> [3, 9, 11]
console.log(widestPasture("_-__-___"));
// -> [3, 5, 7]

这是去除注释后的解决方案的样子。

英文:

You can find a simple solution below which loops through the input characters, finds the pastures and whenever it finds a better pasture than the best so far it will become the new best so far. You can find detailed explanation between the lines.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function widestPasture(input) {
//At the very start we do not have a solution yet, do we default bestSofar to undefined
let bestSofar = undefined;
//lastStartIndex being negative means we are currently not inside a pasture
let lastStartIndex = -1;
//we loop the indexes of the string
for (let i = 0; i &lt; input.length; i++) {
//we check whether the current character is outside of a pasture
if (input[i] !== &#39;_&#39;) {
//if so, and we were in a pasture just before, then we found the end of
//the current pasture at the previous index of i - 1
if (lastStartIndex &gt;= 0) {
//we create a solution array in order to compare to the best so far
let currentPasture = [i - lastStartIndex, lastStartIndex, i - 1];
//if we did not have a best earlier, or the best so far is not
//strictly worse than our current solution, then we replace bestSofar
//with the currentPasture
if ((!bestSofar) || (bestSofar[0] &lt;= currentPasture[0])) bestSofar = currentPasture;
//since we have left the pasture, we mark lastStartIndex with a negative
//value so we will be aware that we are not inside a pasture
lastStartIndex = -1;
}
//the else here means that the character is &#39;_&#39;, so that we are inside a pasture
} else if (lastStartIndex &lt; 0) lastStartIndex = i;
}
//After the loop we check whether we were inside a pasture at the last character
//to cover (literally) edge-cases
if (lastStartIndex &gt;= 0) {
//We create the currentPasture array
let currentPasture = [input.length - lastStartIndex, lastStartIndex, input.length - 1];
//and compare it with the best so far and if it&#39;s better, then it will become
//the new best
if ((!bestSofar) || (bestSofar[0] &lt;= currentPasture[0])) bestSofar = currentPasture;
}
return bestSofar;
}
console.log(widestPasture(&quot;_-___-__-____-______-_&quot;));
// -&gt; [6, 14, 19]
console.log(widestPasture(&quot;_-___-__-___-&quot;));
// -&gt; [3, 9, 11]
console.log(widestPasture(&quot;_-__-___&quot;));
// -&gt; [3, 5, 7]

<!-- end snippet -->

This is how the solution looks alike without the comments

function widestPasture(input) {
let bestSofar = undefined;
let lastStartIndex = -1;
for (let i = 0; i &lt; input.length; i++) {
if (input[i] !== &#39;_&#39;) {
if (lastStartIndex &gt;= 0) {
let currentPasture = [i - lastStartIndex, lastStartIndex, i - 1];
if ((!bestSofar) || (bestSofar[0] &lt;= currentPasture[0])) bestSofar = currentPasture;
lastStartIndex = -1;
}
} else if (lastStartIndex &lt; 0) lastStartIndex = i;
}
if (lastStartIndex &gt;= 0) {
let currentPasture = [input.length - lastStartIndex, lastStartIndex, input.length - 1];
if ((!bestSofar) || (bestSofar[0] &lt;= currentPasture[0])) bestSofar = currentPasture;
}
return bestSofar;
}

答案5

得分: 0

只是为了探索实现相同功能的不同方法,我们可以使用正则表达式和字符串的matchAll方法。

/_+/g是JavaScript中定义的正则表达式。在JavaScript中定义正则表达式时,我们以/(斜杠)字符开头和结尾。然后在这些斜杠之间编写规则。在这里,我写了_+以匹配至少一个或多个下划线的出现。在结束斜杠后,我们可以键入一些额外的字符来定义正则表达式的标志;通过在表达式后键入g,我们定义了一个全局表达式。全局标志允许匹配给定字符串的所有出现,否则我们只会匹配第一个出现。要使用matchAll方法,我们需要有一个全局正则表达式。下面的代码使用了这些功能:

function widestPasture(landscape) {
    const expression = /_+/g;
    var result = [0, 0, 0];
    var allMatches = landscape.matchAll(expression);
    var currentMatch = allMatches.next();
    
    while(!currentMatch.done) {
        let { 0: value, index: tillGreatest } = currentMatch.value;
        if(value.length &gt;= result[0]) {
            result[0] = value.length;
            result[1] = tillGreatest;
            result[2] = tillGreatest+(value.length-1)
        }
        currentMatch = allMatches.next();
    }
    
    return result;
}

console.log(widestPasture("_-___-__-____-______-_"));
// 输出:[6, 14, 19]
console.log(widestPasture("_-___-__-___-"));
// 输出:[3, 9, 11]
console.log(widestPasture("---"));
// 输出:[0, 0, 0]

**附注:**要轻松测试正则表达式并深入了解它们,您可以访问RegExr。它具有漂亮、干净且非常有帮助的用户界面。如果您需要使用正则表达式,这个网站是一个必备工具。

英文:

Just to explore various ways to accomplish the same functionality, we can use Regular Expressions and matchAll method of Strings.

/_+/g is a Regular Expression defined in JavaScript. To define a Regular Expression in JavaScript we begin and end with / (slash) character. Then we write the rules between these shales. Here, I wrote _+ to match occurences with at least one or more underscores. After the ending slash we can type some additional characters to define flags of our Regular Expression; by typing g after the expression, we define a global expression. Global flag allows to match all occurences for the given string, otherwise we would only match the first occurence. To use matchAll method, we need to have a global Regular Expression. Below code uses these features:

function widestPasture(landscape) {
    const expression = /_+/g;
    var result = [0, 0, 0];
    var allMatches = landscape.matchAll(expression);
    var currentMatch = allMatches.next();
    
    while(!currentMatch.done) {
        let { 0: value, index: tillGreatest } = currentMatch.value;
        if(value.length &gt;= result[0]) {
            result[0] = value.length;
            result[1] = tillGreatest;
            result[2] = tillGreatest+(value.length-1)
        }
        currentMatch = allMatches.next();
    }
    
    return result;
}

console.log(widestPasture(&quot;_-___-__-____-______-_&quot;));
// Output: [6, 14, 19]
console.log(widestPasture(&quot;_-___-__-___-&quot;));
// Output: [3, 9, 11]
console.log(widestPasture(&quot;---&quot;));
// Output: [0, 0, 0]

Side note: To test regular expressions easily and explore more about them, you can visit RegExr. It has a nice, clean and very helpful UI. If you ever need to work with Regular Expressions, this website is a must-have tool.

huangapple
  • 本文由 发表于 2023年5月21日 04:46:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76297293.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定