Stack Overflow에서 제가 가장 좋아하는 JS 챌린지 중 하나입니다.

12283 단어 javascript
This one 몇 시간 동안 저를 매료시켰습니다. 흔하지 않은 질문을 발견하고 이를 해결하려고 시도할 시간이 있을 때 저는 행복합니다.

Stack Overflow에서 1년 4개월 동안 활동하고 거의 300개의 질문에 답한 후, 이것은 제가 가장 좋아하는 도전 중 하나입니다.

질문



백엔드를 사용하지 않고 어떻게 모든 사용자를 위해 전반적으로 요소를 무작위로 변경합니까?

글쎄요, 솔직히 말해서 그 질문은 정확히 그와 같지 않았습니다. 사용자는 백엔드 사용을 버리지 않았지만 단지 그것을 더 흥미롭게 만들었습니다.

어떻게 해결 했습니까?



질문을 처음 읽었을 때 백엔드 없이는 불가능하다고 생각했습니다.



그러나 얼마 동안 생각한 후에 나는 이 미스테리를 풀 수 있는 열쇠가 new Date().getTime()이 제공하는 값에 있다는 것을 깨달았습니다. 왜냐하면 는 전 세계 모든 컴퓨터에서 동일하고 고유한 숫자를 반환하기 때문입니다!

⚙️ 작업 스니펫here을 볼 수 있습니다.

코드 설명



먼저 첫 번째 것들..

<div id="root"/>


1970년 1월 1일 이후의 밀리초를 검색한 다음 시간으로 변환합니다.

const hours = Math.round(new Date().getTime()/(1000*60*60))

hours 6자리 숫자를 3자리 숫자로 잘라 배열 안에 추가합니다.

시간에 따라 임의의 숫자를 생성하기 위해 여러 개의 고유 숫자를 가질 목적으로 이 배열을 만들고 있습니다. 이 숫자는 모든 컴퓨터에서 동일합니다.

const numbers = [
    Number(hours.toString().slice(0,2)),
    Number(hours.toString().slice(2,4)),
    Number(hours.toString().slice(4,6))
]


이제 코드가 생성할 난수에 따라 표시할 이미지가 필요합니다. Lorem Picsum에서 일부 URL을 가져와서 배열 안에 추가합니다.

images = [
    'https://picsum.photos/id/237/200/300', 
    'https://picsum.photos/id/236/200/300', 
    'https://picsum.photos/id/235/200/300',
    'https://picsum.photos/id/234/200/300',
    'https://picsum.photos/id/233/200/300',
    'https://picsum.photos/id/232/200/300',
    'https://picsum.photos/id/231/200/300',
    'https://picsum.photos/id/230/200/300',
    'https://picsum.photos/id/229/200/300',
    'https://picsum.photos/id/228/200/300'
  ];


자, 이제 시간 단위로 난수를 반환하는 함수를 만들 차례입니다.

그래서 우리는 그것을 어떻게 합니까?



차근차근 보여드릴께요..
hourlyRand() 내부에서 가장 먼저 빌드하는 것은 전달된 numbersArr(숫자 배열)에 따라 의사 난수를 문자열로 반환하는 화살표 함수입니다.

이것은 지금은 별로 말이 되지 않습니다 😵‍💫 하지만 앞으로 몇 줄 더 걸릴 것입니다.

function hourlyRand(){
  const pseudoRandString = (numbersArr) => {
    let rand = 1
    numbersArr.forEach((n, i) => {
      if(n !== 0) rand = rand * n 
    })
    return rand.toString()
  }  
}


이제 pseudoRandString(numbersArr) 함수를 사용하여 numbers와 같이 맨 위에서 초기화된 pseudoRandString(numbers) 배열을 전달하고 값을 randString 변수에 할당합니다.

  let randString = pseudoRandString(numbers)

randString를 잘라서 두 자리 숫자를 얻을 수 있습니다. 그러나이 숫자는 typeof string이므로 Number로 다시 변환하고 값을 n에 할당해야 합니다.

  // length of the pseudo random number string
  let L = randString.length

  let n = Number(randString.slice(L-3,L-1))


그리고 함수hourlyRand()가 거의 준비되었습니다. 보류 중인 유일한 항목은 반환하는 것입니다n.

완성된 함수hourlyRand()는 다음과 같습니다.

function hourlyRand(){
  const pseudoRandString = (numbersArr) => {
    let rand = 1
    numbersArr.forEach((n, i) => {
      if(n !== 0) rand = rand * n 
    })
    return rand.toString()
  }  

  // get a pseudo random number and convert to string
  let randString = pseudoRandString(numbers)

  // length of the pseudo random number string
  let L = randString.length

  // slice the string and convert to number
  let n = Number(randString.slice(L-3,L-1))

  // return the double digit hourly random number
  return n
}


이제 필요한 모든 것이 있으므로 hourlyRand()에서 두 자리 난수를 가져와 10으로 나눈 다음(이미지가 10개이므로) 반올림합니다.

// pseudo-random number between 0 and 9 
let n = Math.round(hourlyRand()/10)


마지막으로 시간별 임의 이미지를 표시하려면 이미지 배열의 인덱스로 n를 추가하면 됩니다.

const element = document.getElementById('root')
element.innerHTML = '<img src=' + images[n] + '/>'

좋은 웹페이지 즐겨찾기