UNPKG

@onesy/utils

Version:
113 lines (112 loc) 5.2 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const is_1 = __importDefault(require("./is")); const unique_1 = __importDefault(require("./unique")); const equalDeep_1 = __importDefault(require("./equalDeep")); const optionsDefault = { response: 'array', }; // m - array // m! function permutation(value_, options_ = {}) { const options = Object.assign(Object.assign({}, optionsDefault), options_); if ((0, is_1.default)('array', value_)) { const value = (0, unique_1.default)(value_); const length = value.length; const items = length; if (items < 1) return [value]; if (items === 1) return value.map(item_ => [item_]); if (items === 2) return [value, [value[1], value[0]]]; // And other use case, we have less items than the amount of values // [0, 1, 2, 3, 4], or whatever const allIndexes = [...Array(length).keys()]; let item = [...Array(items).keys()]; let index = items - 3; let updated = false; const response = []; if (options.response === 'array') { while (index >= 0) { if (updated) { index = items - 3; updated = false; } // Add item to response response.push(item.slice().map(index_ => value[index_])); // Swap last two and add item to response [item[length - 2], item[length - 1]] = [item[length - 1], item[length - 2]]; response.push(item.slice().map(index_ => value[index_])); if (item[0] === length - 1 && item[1] === length - 2 && (0, equalDeep_1.default)(item, value.slice().reverse())) break; // Move to the left of the values while (true) { const firstPart = item.slice(0, index + 1); const indexNew = allIndexes.filter(index_ => index_ > item[index] && firstPart.indexOf(index_) === -1)[0]; if (!indexNew) { index--; if (index < 0) break; updated = true; } else { // Increment the index // Make rest of the items unique based on the left over indexes from allIndexes item[index] = indexNew; // Make rest of item values unique based on all the left values const part = item.slice(0, index + 1); item = [...part, ...allIndexes.filter(i_ => part.indexOf(i_) === -1).slice(0, items - part.length)]; break; } } } return response; } if (options.response === 'yield') return function* () { while (index >= 0) { if (updated) { index = items - 3; updated = false; } // Add item to response let item_ = item.slice().map(index_ => value[index_]); yield item_; response.push(item_); // Swap last two and add item to response [item[length - 2], item[length - 1]] = [item[length - 1], item[length - 2]]; item_ = item.slice().map(index_ => value[index_]); yield item_; response.push(item_); if (item[0] === length - 1 && item[1] === length - 2 && (0, equalDeep_1.default)(item, value.slice().reverse())) break; // Move to the left of the values while (true) { const firstPart = item.slice(0, index + 1); const indexNew = allIndexes.filter(index_ => index_ > item[index] && firstPart.indexOf(index_) === -1)[0]; if (!indexNew) { index--; if (index < 0) break; updated = true; } else { // Increment the index // Make rest of the items unique based on the left over indexes from allIndexes item[index] = indexNew; // Make rest of item values unique based on all the left values const part = item.slice(0, index + 1); item = [...part, ...allIndexes.filter(i_ => part.indexOf(i_) === -1).slice(0, items - part.length)]; break; } } } return response; }; } } exports.default = permutation;