获取嵌套值的路径

时间:2019-03-08 15:17:39

标签: javascript

我认为这一定是dup,但是我在SO上找不到它。给定这样的对象:

let obj = { keyA: { keyB: 'hi', keyC: { keyD: null } }, keyE: 'hi' }

有没有办法找到指向给定值的键路径,像这样:

keyPaths(obj, 'hi') // -> [ 'keyA.keyB', 'keyE' ]
keyPaths(obj)       // -> [ 'keyA.keyB.keyD' ]

我尝试调整一些答案,这些答案找到了深知密钥的值,而且我几乎能够适应this one that finds deep nulls,但我不知道该如何找回路径,而不仅仅是解决最深的键。

3 个答案:

答案 0 :(得分:2)

我会像这样进行深度优先搜索:

let obj = { keyA: { keyB: 'hi', keyC: { keyD: null } }, keyE: 'hi' }

function keyPaths(parent, value = null, chain) {
  let allResults = [];
  for (const prop in parent) {
    if (parent.hasOwnProperty(prop)) {
      const element = parent[prop];
      const newChain = chain ? chain + '.' + prop : prop;
      if (element === value) {
        allResults.push(newChain);
      }
      else if (Object.keys(prop).length > 1) {
        allResults = [...allResults, ...keyPaths(element, value, newChain)];
      }
    }
  }
  return allResults;
}

console.log(keyPaths(obj, 'hi')) // -> [ 'keyA.keyB', 'keyE' ]
console.log(keyPaths(obj))       // -> [ 'keyA.keyB.keyC' ]

基本上,我检查给定元素的所有属性是否有匹配的值。如果某个属性与该值不匹配,但具有子属性,那么我将递归调用该函数,并合并调用迭代和递归调用的结果。

答案 1 :(得分:2)

您可以通过在递归函数中使用reduce来做到这一点。该函数将返回一个数组,然后您可以将map()转换为所需的任何字符串值。

let obj = { keyA: { keyB: 'hi', keyC: { keyD: null } }, keyE: 'hi' }

function keyPaths(obj, val, path = [] ){
  if (!obj) return 
  return Object.entries(obj).reduce((res, [k, v]) => {
    let p = [...path, k]
    if (v == val) res.push(p)
    else if (v && typeof v == 'object') res.push(...keyPaths(v, val, p))
    return res
  }, [])
}

console.log(keyPaths(obj, 'hi').map(a => a.join('.')))
console.log(keyPaths(obj).map(a => a.join('|')))

答案 2 :(得分:0)

如果可以使用Lodash + Deepdash,则:

public void stats()
    {

        System.out.println("\f");
        int numRoyalFlushes = 0;
        int numStraightFlushes = 0;
        int numFourKinds = 0;
        int numFullHouses = 0;
        int numFlushes = 0;
        int numStraights = 0;
        int numThreeKinds = 0;
        int numTwoPair = 0;
        int numPair = 0;
        int numHighCard = 0;
        Deck deck = new Deck();
        for(int i = 0;i < 1000000;i++)
        {
            deck.shuffle();
            PokerHand cards = new PokerHand(deck, 5);
            int xd = cards.evaluate(cards);
            if(xd == 9)
                numRoyalFlushes++;
            else if(xd == 8)
                numStraightFlushes++;
            else if(xd == 7)
                numFourKinds++;
            else if(xd == 6)
                numFullHouses++;
            else if(xd == 5)
                numFlushes++;
            else if(xd == 4)
                numStraights++;
            else if(xd == 3)
                numThreeKinds++;
            else if(xd == 2)
                numTwoPair++;
            else if(xd == 1)
                numPair++;
            else if(xd == 0)
                numHighCard++;
            cards.putCardsBack(deck);
        }
        System.out.println("After 1 million hands, the stats are: ");
        System.out.println(numRoyalFlushes + " Royal Flushes");
        System.out.println(numStraightFlushes + " Straight Flushes");
        System.out.println(numFourKinds + " Four of a Kinds");
        System.out.println(numFullHouses + " Full Houses");
        System.out.println(numFlushes + " Flushes");
        System.out.println(numStraights + " Straights");
        System.out.println(numThreeKinds + " Three of a Kinds");
        System.out.println(numTwoPair + " Two Pairs");
        System.out.println(numPair + " Pairs");
        System.out.println(numHighCard + " High Cards");
    }

public void selectionSort(PokerHand hand)
    {

        Card temp = new Card(0,0);
        for(int i = 0;i < hand.size()-1;i++)
        {
            int smallestIndex = i;
            for(int j = i+1;j < hand.size();j++)
            {
                if(hand.get(j).getRank() < hand.get(smallestIndex).getRank()) // error occurs on this line
                {
                    smallestIndex = j;
                }
            }
            if(smallestIndex != i)
            {
                temp = hand.get(smallestIndex);
                hand.set(smallestIndex,hand.get(i));
                hand.set(i,temp);
            }
        }
    }

Codepen is here