2017-08-16 33 views
1

我想寫一個函數,從6個骰子的數組中篩選出三元組。有沒有簡單的方法來使用Lodash或Underscore來做到這一點?如何從重複的數組中刪除* some *項目? (Lodash /下劃線的首選)

noTriplets([1,1,1,3,3,5]) // = [3,3,5] 
 
noTriplets([1,1,1,1,3,5]) // = [1,3,5] 
 
noTriplets([1,1,1,1,1,5]) // = [1,1,5] 
 
noTriplets([1,1,1,5,5,5]) // = [] 
 
noTriplets([1,1,1,1,1,1]) // = []

+0

這取決於你考慮容易...你搞什麼名堂到目前爲止做了什麼? – Teemu

+0

嘿喬 - 你能確認你要找的條件嗎?在示例3中,您在數組中返回了兩個'1',但在示例4和5中,返回none。條件是每次有一個數字有三個時,刪除這三個,但如果有四個,則您想要返回1.如果有6個,您希望因爲刪除3和3而不返回任何一個。是這樣嗎? –

+0

@ChristopherMesser你是對的。我想刪除數組中的任何三元組。 –

回答

2

這是一個有點粗糙和骯髒的,但它並不需要你提前知道你的三胞胎。在noTriplets()之內 - 我創建了一個快速哈希映射,然後遍歷該對象。循環邏輯處理三重件。

const arrayTestOne = [1,1,1,3,3,5]; 
 
const arrayTestTwo = [1,1,1,1,3,3,5]; 
 
const arrayTestThree = [1,1,1,3,3,3]; 
 
const arrayTestFour = [1,1,1,1,3,3,3,5,5,5,5,5,5,5,5,5,5,5,5,7,7]; 
 

 
const hashMap = (array) => array.reduce((allNums, num) => { 
 
    if (num in allNums) { 
 
    allNums[num]++ 
 
    } 
 
    else { 
 
\t allNums[num] = 1 
 
    } 
 
    return allNums 
 
}, {}) 
 

 
function noTriplets(arr) { 
 
    let newArr = []; 
 
    let obj = hashMap(arr); 
 
    for (var key in obj) { 
 
    for (let i=0; i < obj[key] % 3; i++) { 
 
     newArr.push(key) 
 
    } 
 
    } 
 
    console.log(newArr) 
 
} 
 

 
noTriplets(arrayTestOne) 
 
noTriplets(arrayTestTwo) 
 
noTriplets(arrayTestThree) 
 
noTriplets(arrayTestFour)

+0

這是我正在尋找的方法,除了使用lodash可以使實現更短。這裏是我對它的看法:函數noTriplets(arr)var hashMap = _.countBy(arr); return _.flatten(_。keys(hashMap).map(n => Array(hashMap [n]%3).fill(n))) } –

1

你可以使用一個計數的每個項目和計算有多少項目忽略。

function noTriplets(array) { 
 
    var hash = {}; 
 

 
    array.forEach(function (a) { 
 
     hash[a] = hash[a] || { count: 0 }; 
 
     hash[a].ignore = Math.floor(++hash[a].count/3) * 3; 
 
    }); 
 

 
    return array.filter(function (a, i) { 
 
     return --hash[a].ignore < 0; 
 
    }); 
 
} 
 

 
console.log(noTriplets([1, 1, 1, 3, 3, 5])); // [3, 3, 5] 
 
console.log(noTriplets([1, 1, 1, 1, 3, 5])); // [1, 3, 5] 
 
console.log(noTriplets([1, 1, 1, 1, 1, 5])); // [1, 1, 5] 
 
console.log(noTriplets([1, 1, 1, 5, 5, 5])); // [] 
 
console.log(noTriplets([1, 1, 1, 1, 1, 1])); // []
.as-console-wrapper { max-height: 100% !important; top: 0; }

1

您可以使用一個對象來記錄值,然後生成使用以前的對象的新數組。

function noTriplets(arr){ 
 
    var tripletCount = arr.reduce((dice,value) => { 
 
    dice[value] = dice[value] || { count : 0 }; 
 
    dice[value].count = (dice[value].count + 1) % 3; 
 
    return dice; 
 
    },{}); 
 
    
 
    return Object.keys(tripletCount).reduce((arr,key) => { 
 
    return arr.concat(new Array(tripletCount[key].count).fill(key)); 
 
    },[]); 
 
} 
 

 
console.log(noTriplets([1, 1, 1, 3, 3, 5])); // [3, 3, 5] 
 
console.log(noTriplets([1, 1, 1, 1, 3, 5])); // [1, 3, 5] 
 
console.log(noTriplets([1, 1, 1, 1, 1, 5])); // [1, 1, 5] 
 
console.log(noTriplets([1, 1, 1, 5, 5, 5])); // [] 
 
console.log(noTriplets([1, 1, 1, 1, 1, 1])); // []

1

我用純JS通用的解決方案。您可以指定應該刪除多少個重複項目。例如,這裏創建了noDoubles,noTripletsnoQuadruples方法。

function isArrayWithIdenticalElements(array) { 
 
    return array.length > 1 && !!array.reduce(function(a, b){ return (a === b) ? a : NaN; }); 
 
} 
 

 
function noRepetition(numberOfRepetition, array) { 
 
    var sliceLength = numberOfRepetition - 1; 
 
    var pointer = sliceLength; 
 
    var element = array[pointer]; 
 

 
    while (element) { 
 
    if (isArrayWithIdenticalElements(array.slice(pointer - sliceLength, pointer + 1))) { 
 
     array.splice(pointer - sliceLength, numberOfRepetition); 
 

 
     pointer = pointer - sliceLength; 
 
     element = array[pointer]; 
 
    } else { 
 
     pointer = pointer + 1; 
 
     element = array[pointer]; 
 
    } 
 
    } 
 

 
    return array; 
 
} 
 

 
var noDoubles = noRepetition.bind(null, 2); 
 
var noTriplets = noRepetition.bind(null, 3); 
 
var noQuadruples = noRepetition.bind(null, 4); 
 

 
console.log('noTriplets([1,1,1,3,3,5] ==> ', noTriplets([1,1,1,3,3,5])); // = [3,3,5] 
 
console.log('noTriplets([1,1,1,1,3,5] ==> ', noTriplets([1,1,1,1,3,5])); // = [1,3,5] 
 
console.log('noTriplets([1,1,1,1,1,5] ==> ', noTriplets([1,1,1,1,1,5])); // = [1,1,5] 
 
console.log('noTriplets([1,1,1,5,5,5] ==> ', noTriplets([1,1,1,5,5,5])); // = [] 
 
console.log('noTriplets([1,1,1,1,1,1] ==> ', noTriplets([1,1,1,1,1,1])); // = [] 
 

 
console.log('noQuadruples([1,1,1,3,3,5] ==> ', noQuadruples([1,1,1,3,3,5])); // = [1,1,1,3,3,5] 
 
console.log('noQuadruples([1,1,1,1,3,5] ==> ', noQuadruples([1,1,1,1,3,5])); // = [3,5] 
 

 
console.log('noDoubles([1,1,1,5,5,5] ==> ', noDoubles([1,1,1,5,5,5])); // = [1,5]

0

偉大的答案!閱讀大家的回答後,特別是克里斯托弗·梅塞爾的,我想出了一個基於lodash版本:

function noTriplets(arr) { 
 
    var hashMap = _.countBy(arr) 
 
    var filler = n => Array(hashMap[n] % 3).fill(n) 
 
    return _.flatten(_.keys(hashMap).map(filler)) 
 
}