# 一天一個仿lodash函數實現-xor

xor 數組類異或，其實是找出一堆數組裏面，只出現一次的元素集合。

``````function xor0(...arrays){
const map = {};
const all = arrays.reduce((pre, cur) => {
cur.forEach(item=>{
map[item] = map[item]?map[item]+1:1
})
return pre.concat(cur)
}, [])
let index = 0;
const result = [];
while(index<all.length){
const cur = all[index];
if(map[cur]===1){
result.push(cur);
}
}
return result;
}
function difference(arr, ...rest) {
// 扁平化rest
const target = rest.reduce((pre, cur) => {
return pre.concat(cur)
}, [])
return arr.filter(item => !target.includes(item))
}
function xor(...arrays){
const len = arrays.length;
const result = Array(len);
let index = 0;
while(index<len){
let oIndex = 0;
while(oIndex<len){
if(oIndex!==index){
result[index] = difference(result[index]||arrays[index], arrays[oIndex])
}
oIndex++
}
index++;
}
return result.reduce((pre, cur)=>{
return pre.concat(cur);
}, [])
}
function differenceBy(arr, ...args) {
if(args.length<2) {
throw new Error('iteratee missing or target array missing')
}
const rest = args.slice(0, args.length-1)
const keyOrFunc = args[args.length-1]
let iteratee;
if(typeof keyOrFunc === 'string') {
iteratee = (item) => item[keyOrFunc]
}else{
iteratee = keyOrFunc
}
// 扁平化rest
const target = rest.reduce((pre, cur) => {
return pre.concat(cur.map(i=>iteratee(i)))
}, []);
return arr.filter(item => !target.includes(iteratee(item)))
}

function xorBy(...args){
const iteratee = args[args.length-1];
const it = typeof iteratee === 'string'?x=>x[iteratee]:iteratee;
const arrays = args.slice(0, args.length-1);
const len = arrays.length;
const result = Array(len);
let index = 0;
while(index<len){
let oIndex = 0;
while(oIndex<len){
if(oIndex!==index){
result[index] = differenceBy(result[index]||arrays[index], arrays[oIndex], it)
}
oIndex++
}
index++;
}
return result.reduce((pre, cur)=>{
return pre.concat(cur);
}, [])
}

function differenceWith(arr, ...args) {
if(args.length<2) {
throw new Error('iteratee missing or target array missing')
}
const rest = args.slice(0, args.length-1)
const comparator = args[args.length-1]

// 扁平化rest
const target = rest.reduce((pre, cur) => {
return pre.concat(cur)
}, []);
return arr.filter(item => {
for(let i=0;i<target.length;i++) {
if(comparator(target[i], item)) {
return false;
}
}
return true
})
}

function xorWith(...args){
const iteratee = args[args.length-1];
const arrays = args.slice(0, args.length-1);
const len = arrays.length;
const result = Array(len);
let index = 0;
while(index<len){
let oIndex = 0;
while(oIndex<len){
if(oIndex!==index){
result[index] = differenceWith(result[index]||arrays[index], arrays[oIndex], iteratee)
}
oIndex++
}
index++;
}
return result.reduce((pre, cur)=>{
return pre.concat(cur);
}, [])
}
``````