Javascript 객체에서 임의 속성 선택


89

{ 'cat': 'meow', 'dog': 'woof'...}와 같은 자바 스크립트 객체가 있다고 가정 해 보겠습니다. :

function pickRandomProperty(obj) {
    var prop, len = 0, randomPos, pos = 0;
    for (prop in obj) {
        if (obj.hasOwnProperty(prop)) {
            len += 1;
        }
    }
    randomPos = Math.floor(Math.random() * len);
    for (prop in obj) {
        if (obj.hasOwnProperty(prop)) {
            if (pos === randomPos) {
                return prop;
            }
            pos += 1;
        }
    }       
}

OP, 선택한 답변을 다시 선택하십시오 ... @kennytm이 다른 사람보다 먼저 올바르게 답변했습니다. (작동하지만) 다윗의 대답은 코딩 단순히 나쁜
수직 동기화

질문과 답변은 실제로 질문 제목에서 알 수 있듯이 임의의 속성이 아닌 임의의 개체 속성 의 값 을 반환 하는 것을 찾습니다 .
kontur

답변:


183

선택한 답변이 잘 작동합니다. 그러나이 답변은 더 빨리 실행됩니다.

var randomProperty = function (obj) {
    var keys = Object.keys(obj);
    return obj[keys[ keys.length * Math.random() << 0]];
};

3
그것은 루프를 사용하지 않기 때문에이 좋다
도미닉

14
나는 몇 가지 테스트를 수행했으며 선택한 답변이 잘 작동하고 재산 선택이 편향되지 않은 것으로 나타났습니다 (응답 간의 추측과 달리). 그러나 170,000 개의 키가있는 개체를 테스트했으며 여기의 솔루션은 선택한 솔루션보다 약 두 배 빠릅니다.
Dragonfly

8
<< 0 (왼쪽으로 0만큼 비트 이동)은 Math.round ()를 작성하는 속기 방법입니까?
SystemicPlural

4
이 jsperf jsperf.com/random-object-property-selection 은이 답변과 선택한 답변을 벤치마킹합니다. 이 답변은 작은 개체 (100 개의 속성)에 대해 3 배 더 나은 성능을 제공합니다. 더 큰 개체 (10 만 속성)는 차이가 2 배 더 좋아집니다.
Constablebrew

2
@MuhammadUmer-아니요 Math.random(). [0,1) 범위의 숫자를 반환합니다.
Yay295 2015

74

스트림에서 임의의 요소 선택

function pickRandomProperty(obj) {
    var result;
    var count = 0;
    for (var prop in obj)
        if (Math.random() < 1/++count)
           result = prop;
    return result;
}

2
ECMAScript 표준은 항상 동일한 순서로 순회되는 속성에 대해 언급합니까? 대부분의 구현에서 객체는 안정적인 순서를 갖지만 동작은 사양에 정의되어 있지 않습니다. stackoverflow.com/questions/280713/…
Brendan Berg

4
이것은 객체의 첫 번째 요소쪽으로 기울어 진 것 같습니다. 나는 아직 이유를 찾지 못했습니다!
Cole Gleason 2014 년

7
이렇게하면 첫 번째 속성 (Math.random은 항상 <1)이 선택되지 않으며 그 후에 각 숫자가 선택 될 확률이 0.5입니다. 등 4 일에 대 3의 두 번째 속성 0.5, 0.25, 0.125 그래서
SystemicPlural

4
일부 수정 :이 기능은 첫 번째 속성을 선택할 수 있습니다. 첫 번째 반복에서 카운트의 접두사 증가는 방정식의 오른쪽이 1/1 == 1로 평가되도록합니다. Math.random은 항상 범위 [0,1) (1을 제외하고 0에서 1)에 있으므로 식이 true로 평가되고 첫 번째 속성이 선택됩니다. 무작위 선택의 분포에 관한 한 균일합니다. 하나의 속성으로 선택 될 확률은 100 %입니다. 둘 중 하나가 선택 될 확률이 50 %입니다. 3은 33.3 %입니다. 등등. 이 솔루션에는 최소한의 메모리 공간이 있습니다.
Constablebrew

3
@davidhadas 세 가지 요소의 시퀀스를 고려하십시오. 첫 번째는 1의 확률로 선택됩니다. 그러나 1/2의 확률로 두 번째 요소로 대체 ​​될 수 있습니다 (즉시 반환되지 않음에 유의하십시오!). 두 번째 요소는 1/3의 확률로 세 번째 요소로 대체 ​​될 수 있습니다. 그래서 우리는 P (first) = P (first picked) * P (second not picked) * P (third not picked) = 1 * 1/2 * 2/3 = 1/3; P (초) = P (두 번째 선택) * P (세 번째 선택 안 함) = 1/2 * 1/3 = 1/3; P (세 번째) = P (세 번째 선택) = 1/3.
Martin Törnwall

19

나는 예제 중 어느 것도 충분히 혼란스럽지 않다고 생각했기 때문에 여기에 동일한 작업을 수행하는 매우 읽기 어려운 예제가 있습니다.

편집 : 동료가 당신을 미워하기를 원하지 않는 한 이것을하지 말아야합니다.

var animals = {
    'cat': 'meow',
    'dog': 'woof',
    'cow': 'moo',
    'sheep': 'baaah',
    'bird': 'tweet'
};

// Random Key
console.log(Object.keys(animals)[Math.floor(Math.random()*Object.keys(animals).length)]);

// Random Value
console.log(animals[Object.keys(animals)[Math.floor(Math.random()*Object.keys(animals).length)]]);

설명:

// gets an array of keys in the animals object.
Object.keys(animals) 

// This is a number between 0 and the length of the number of keys in the animals object
Math.floor(Math.random()*Object.keys(animals).length)

// Thus this will return a random key
// Object.keys(animals)[0], Object.keys(animals)[1], etc
Object.keys(animals)[Math.floor(Math.random()*Object.keys(animals).length)]

// Then of course you can use the random key to get a random value
// animals['cat'], animals['dog'], animals['cow'], etc
animals[Object.keys(animals)[Math.floor(Math.random()*Object.keys(animals).length)]]

긴 손, 덜 혼동 :

var animalArray  = Object.keys(animals);
var randomNumber = Math.random();
var animalIndex  = Math.floor(randomNumber * animalArray.length);

var randomKey    = animalArray[animalIndex];
// This will course this will return the value of the randomKey
// instead of a fresh random value
var randomValue  = animals[randomKey]; 

4
이것은 실제로 가장 합리적인 해결책입니다
Paweł

2
설명과 모든 것을 포함하여 이것을 가장 좋아하고 실제 예제 POJO도 포함합니다. 훌륭한 답변, 더 많은 찬성 투표가 필요합니다! 모든 것을 이해하기 훨씬 쉽게 만듭니다!
Tigerrrrr 2019

1
최고의 솔루션! 이것은 가장 많이 투표되어야합니다.
nilsoviani

15

개체를 걷는 동안 키 배열을 만들 수 있습니다.

var keys = [];
for (var prop in obj) {
    if (obj.hasOwnProperty(prop)) {
        keys.push(prop);
    }
}

그런 다음 키에서 임의로 요소를 선택합니다.

return keys[keys.length * Math.random() << 0];

13
Object.keys는 여기에서 유용합니다var keys = Object.keys(obj)
whadar

Dang <<은 Math.floor ()를 사용하는 것보다 훨씬 더 우아합니다. 나는 정말로 내려서 그 비트 연산자를 사용하는 방법을 배워야합니다.
Paul J

5
이 경우 비트 연산자의 사용은 해킹 일 가능성이 더 높습니다. 입력으로 정수가 필요하기 때문에 숫자를 변환합니다. << 0정수에 적용하면 아무 작업도 수행되지 않습니다. parseInt()같은 일을 할 것입니다. 따라서 이해하기 어려운 코드를 작성하는 것 외에는 여기서 배울 것이 없습니다.
Landunder

13

라이브러리를 사용할 수 있다면 Lo-Dash JS 라이브러리에 이러한 경우에 매우 유용한 메서드가 많이 있음을 알 수 있습니다. 이 경우 계속해서 확인하십시오 _.sample().

(참고로 Lo-Dash 규칙은 라이브러리 객체의 이름을 _로 지정합니다. 동일한 페이지에서 설치를 확인하여 프로젝트에 맞게 설정하는 것을 잊지 마십시오.)

_.sample([1, 2, 3, 4]);
// → 2

귀하의 경우 다음을 사용하십시오.

_.sample({
    cat: 'meow',
    dog: 'woof',
    mouse: 'squeak'
});
// → "woof"

3

underscore.js 를 사용하는 경우 다음 을 수행 할 수 있습니다.

_.sample(Object.keys(animals));

특별한:

여러 개의 임의 속성이 필요한 경우 숫자를 추가합니다.

_.sample(Object.keys(animals), 3);

임의의 속성 만있는 새 개체가 필요한 경우 :

const props = _.sample(Object.keys(animals), 3);
const newObject = _.pick(animals, (val, key) => props.indexOf(key) > -1);

0

이를 수행하는 또 다른 간단한 방법은 적용되는 함수를 정의하는 것입니다. Math.random() .

이 함수는 'min'범위의 임의의 정수를 반환합니다.

function getRandomArbitrary(min, max) {
  return Math.floor(Math.random() * (max - min) + min);
}

그런 다음 위의 함수를 매개 변수로 제공 할 때마다 Javascript 객체에서 '키', '값'또는 '둘 다'를 추출합니다.

var randNum = getRandomArbitrary(0, 7);
var index = randNum;
return Object.key(index); // Returns a random key
return Object.values(index); //Returns the corresponding value.

Object.values ​​(someObject) [index]를 의미합니까?
Bemmu

인덱스 I 생성 된 저장하는 데 사용했다고 변수 임의의 수는 단지 용기, 아무것도 특별하다. 생성 된 숫자를 다른 변수에 저장하지 않았다면 함수의 각 인스턴스는 호출 getRandomArbitrary될 때마다 새로운 난수를 생성합니다.
Sushant Chaudhary

0

JSON 객체에서 다음을 배치해야합니다.

var object={
  "Random": function() {
    var result;
    var count = 0;
    for (var prop in this){
      if (Math.random() < 1 / ++count&&prop!="Random"){
        result = this[prop];
      }
    }
    return result;
  }
}

이 함수는 임의 속성의 내부를 반환합니다.


0

다음 코드를 사용하여 JavaScript 객체에서 임의의 속성을 선택할 수 있습니다.

function randomobj(obj) {
var objkeys = Object.keys(obj)
return objkeys[Math.floor(Math.random() * objkeys.length)]
}
var example = {foo:"bar",hi:"hello"}
var randomval = example[randomobj(example)] // will return to value
// do something

이 코드가 질문에 답할 수 있지만 문제를 해결하는 방법 및 / 또는 이유에 대한 추가 컨텍스트를 제공하면 답변의 장기적인 가치가 향상됩니다.
Nic3500
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.