如何将一个项目列表映射’n’次,但每次都循环回到开头

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

How to map a List of items 'n' times, but loop back to the beginning each time

问题

I'm fairly new to React, so there is probably just an easier way to do this.

But I have a List of items

```jsx
const NOTES = [
  { id: 0, val: "C" },
  { id: 1, val: "C#" },
  { id: 2, val: "D" },
  { id: 3, val: "D#" },
  { id: 4, val: "E" },
  { id: 5, val: "F" },
  { id: 6, val: "F#" },
  { id: 7, val: "G" },
  { id: 8, val: "G#" },
  { id: 9, val: "A" },
  { id: 10, val: "A#" },
  { id: 11, val: "B" },
];

The requirement is that a user will give a number of notes to display.
So for example, if the user gives 14 you would display

C, C#, D, D#, E, F, F#, G, G#, A, A#, B, C, C#

I currently have this

const keys = [...Array(13).keys()];
console.log("keys: ", keys);
return (
  <div>
    {keys.map((item) => (
      <div key={item}>{NOTES[item % 12].val}</div>
    ))}
  </div>
);

But because there are only 12 elements in the List, I get an error. Is there any way to make it so that when it reaches the last element in the List, I go back to the first element and continue 'n' times?


<details>
<summary>英文:</summary>

I&#39;m fairly new to React, so there is probably just an easier way to do this.

But I have a List of items

const NOTES = [
{ id: 0, val: "C" },
{ id: 1, val: "C#" },
{ id: 2, val: "D" },
{ id: 3, val: "D#" },
{ id: 4, val: "E" },
{ id: 5, val: "F" },
{ id: 6, val: "F#" },
{ id: 7, val: "G" },
{ id: 8, val: "G#" },
{ id: 9, val: "A" },
{ id: 10, val: "A#" },
{ id: 11, val: "B" },
];


The requirement is that a user will give a number of notes to display. 
So for example, if the user gives 14 you would display


C, C#, D, D#, E, F, F#, G, G#, A, A#, B, C, C#




I currently have this

const keys = [...Array(13).keys()];
console.log("keys: ", keys);
return (
<div>
{keys.map((item) => (
<div key={item}>{NOTES[item].val}</div>
))}
</div>
);


But because there are only 12 elements in the List, I get an error. Is there any way to make it so that when it reaches the last element in the List, I go back to the first element and continue &#39;n&#39; times?

</details>


# 答案1
**得分**: 1

不要使用keys.map,可以创建一个函数。这个函数将接收一个参数(在这个示例中是需要的音符数量,例如14)。然后在函数内部声明NOTES数组,将计数器设置为0(作为变量),创建一个空数组,稍后要填充信息。定义一个循环,从0到你定义的参数。在循环内部执行数组的push操作,例如:myArray.push(NOTES
0
+
网站访问量
)。然后执行counter++操作。如果计数器等于11,则将其重新设置为0。然后在循环之外返回数组。然后将keys.map替换为myFunc(16).map,每个项将是你寻找的数组。希望这能帮助你找到正确的解决方案。 <details> <summary>英文:</summary> Instead of using keys.map You can create a function This function will receive a parameter (the number of times that you need notes in this example 14) Then inside the func declare the NOTES array Set a counter in 0 (let variable) Set an empty array that you are going to fill with info after Define a for loop that is going from 0 to the param that you defined Inside for do an array.push Example: myArray.push(NOTES
0
+
网站访问量
) Execute counter++ If the counter is 11 set it to 0 again Then outside for loop return the array Then replace keys.map with myFunc(16).map And each item will be the array that are you looking for Hope this helps you to find the right solution </details> # 答案2 **得分**: 0 Jurgen的解决方案是正确的。 在过去,我曾因没有为我的数组指定类型而出现错误。 ```javascript var arr: string[] = [];

所以完整的解决方案应该是这样的:

var arr: string[] = [];
var c = 2;
for (var i = 0; i < numFrets; i++) {
  arr[i] = NOTES[c].val;
  c++;
  if (c == 12) {
    c = 0;
  }
}

return (
  <div>
    {arr.map((item) => (
      <div>{item}</div>
    ))}
  </div>
);
英文:

In case anyone is stupid like me, Jurgen's solution is the way to go.

I got errors in the past due to now giving a type for my array.

  var arr: string[] = [];

So the full solution would be something like this

var arr: string[] = [];
  var c = 2;
  for (var i = 0; i &lt; numFrets; i++) {
    arr[i] = NOTES[c].val;
    c++;
    if (c == 12) {
      c = 0;
    }
  }

  return (
    &lt;div&gt;
      {arr.map((item) =&gt; (
        &lt;div&gt;{item}&lt;/div&gt;
      ))}
    &lt;/div&gt;
  );

答案3

得分: 0

你可以使用模数来回到数组的起始位置:

const NOTES = [{
    id: 0,
    val: "C"
  },
  {
    id: 1,
    val: "C#"
  },
  {
    id: 2,
    val: "D"
  },
  {
    id: 3,
    val: "D#"
  },
  {
    id: 4,
    val: "E"
  },
  {
    id: 5,
    val: "F"
  },
  {
    id: 6,
    val: "F#"
  },
  {
    id: 7,
    val: "G"
  },
  {
    id: 8,
    val: "G#"
  },
  {
    id: 9,
    val: "A"
  },
  {
    id: 10,
    val: "A#"
  },
  {
    id: 11,
    val: "B"
  }
];

function getNoteSequence(numOfNotes) {
  numOfNotes = numOfNotes || 0;

  const totalNotesDefined = NOTES.length;

  const result = [];
  for (let currNote = 0; currNote < numOfNotes; currNote++) {
    result.push(NOTES[currNote % totalNotesDefined]);
  }

  return result;
}

function generateHTML() {
  const noteSequence = getNoteSequence(14);

  document
    .querySelector('#notes-container')
    .innerHTML = noteSequence
      .map((note) => `<div key="${ note.id }">${ note.val }</div>`)
      .join('');
}

generateHTML();
<div id="notes-container"></div>
英文:

You can use modulo to loop back to the start of the array:

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

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

const NOTES = [{
id: 0,
val: &quot;C&quot;
},
{
id: 1,
val: &quot;C#&quot;
},
{
id: 2,
val: &quot;D&quot;
},
{
id: 3,
val: &quot;D#&quot;
},
{
id: 4,
val: &quot;E&quot;
},
{
id: 5,
val: &quot;F&quot;
},
{
id: 6,
val: &quot;F#&quot;
},
{
id: 7,
val: &quot;G&quot;
},
{
id: 8,
val: &quot;G#&quot;
},
{
id: 9,
val: &quot;A&quot;
},
{
id: 10,
val: &quot;A#&quot;
},
{
id: 11,
val: &quot;B&quot;
}
];
function getNoteSequence(numOfNotes) {
numOfNotes = numOfNotes || 0;
const totalNotesDefined = NOTES.length;
const result = [];
for (let currNote = 0; currNote &lt; numOfNotes; currNote++) {
result.push(NOTES[currNote % totalNotesDefined]);
}
return result;
}
function generateHTML() {
const noteSequence = getNoteSequence(14);
document
.querySelector(&#39;#notes-container&#39;)
.innerHTML = noteSequence
.map((note) =&gt; `&lt;div key=&quot;${ note.id }&quot;&gt;${ note.val }&lt;/div&gt;`)
.join(&#39;&#39;);
}
generateHTML();

<!-- language: lang-html -->

&lt;div id=&quot;notes-container&quot;&gt;&lt;/div&gt;

<!-- end snippet -->

答案4

得分: 0

如Jurgen已经提到的,下面已经完成了相同的事情:

const NOTES = [
  { id: 0, val: "C" },
  { id: 1, val: "C#" },
  { id: 2, val: "D" },
  { id: 3, val: "D#" },
  { id: 4, val: "E" },
  { id: 5, val: "F" },
  { id: 6, val: "F#" },
  { id: 7, val: "G" },
  { id: 8, val: "G#" },
  { id: 9, val: "A" },
  { id: 10, val: "A#" },
  { id: 11, val: "B" },
];

const userInput = 14;
const keys = [...Array(13).keys()];
console.log("keys: ", keys);

const prepareFinalList = () => {
  const finalListEl = [];
  let userInputCounter = 0;
  let i = 0;

  // this userInput variable required to break the loop
  while (userInputCounter <= userInput) {
    if (i > NOTES.length - 1) {
      i = 0;
    }

    const item = NOTES[i];

    finalListEl[userInputCounter] = (<div key={item.id}>{item.val}</div>)

    i++;
    userInputCounter++;
  }

  // this will have the mapped dom structure
  return finalListEl;
};

return (
  <div>
    {/* 
    1. instead of using map you should use different loop. Maybe normal for loop or while loop 
       and prepared your own Dom's array.

    */}
    {prepareFinalList()}
  </div>
);
英文:

As jurgen has already mentioned, the same thing has been done below:

const NOTES = [
{ id: 0, val: &quot;C&quot; },
{ id: 1, val: &quot;C#&quot; },
{ id: 2, val: &quot;D&quot; },
{ id: 3, val: &quot;D#&quot; },
{ id: 4, val: &quot;E&quot; },
{ id: 5, val: &quot;F&quot; },
{ id: 6, val: &quot;F#&quot; },
{ id: 7, val: &quot;G&quot; },
{ id: 8, val: &quot;G#&quot; },
{ id: 9, val: &quot;A&quot; },
{ id: 10, val: &quot;A#&quot; },
{ id: 11, val: &quot;B&quot; },
];
const userInput = 14;
const keys = [...Array(13).keys()];
console.log(&quot;keys: &quot;, keys);
const prepareFinalList = () =&gt; {
const finalListEl = [];
let userInputCounter = 0;
let i = 0;
// this userInput variable required to break the loop
while(userInputCounter &lt;= userInput) {
if (i &gt; NOTES.length - 1) {
i = 0;
}
const item = NOTES[i];
finalListEl[userInputCounter] = (&lt;div key={item.id}&gt;{item.val}&lt;/div&gt;)
i++;
userInputCounter++;
}
// this will have the mapped dom structure
return finalListEl;
};
return (
&lt;div&gt;
{/* 
1. instead of using map you should use different loop. Maybe normal for loop or while loop 
and prepared your own Dom&#39;s array.
*/}
{prepareFinalList()}
&lt;/div&gt;
);

huangapple
  • 本文由 发表于 2023年6月16日 07:19:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/76486054.html
匿名

发表评论

匿名网友

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

确定