我认为这一定是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,但我不知道该如何找回路径,而不仅仅是解决最深的键。
答案 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);
}
}
}