< 返回 Anicca 總索引
Algorithm
title: Algorithm
date: '2011-01-11'
tags: ['code']
draft: false
Filter
/**
* 過濾陣列中相同項 從陣列中,刪除重複項 [簡單的陣列項]
*/
const strings = ["AA", "BB", "AA", "AD", "BC", "AC", "AD"];
// filter函式本來就返回新陣列,所以將邏輯寫在內中,最終返回新陣列。
const filteredStrings = strings.filter((item, index) => {
// 如果當前專案的索引與該專案的第一次出現相同,則返回到新陣列
// console.log("ITEM:", item, `|| ${strings.indexOf(item)}`);
return strings.indexOf(item) === index;
});
// console.log("刪除重複項", filteredStrings);
const arr1 = [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4];
const arr2 = arr1.filter((element, index, self) => {
return self.indexOf(element) === index;
});
console.log(arr2); // [1, 2, 3, 5, 4]
console.log(arr1); // [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4]
// 用於 過濾陣列中相同的物件
const books = [
{
name: "1",
author: "A",
},
{
name: "2",
author: "B",
},
{
author: "B",
name: "2",
},
];
/**
* 過濾陣列中相同的物件 從陣列中,刪除重複項 [物件型別的陣列項]
* @param {*} arr 待刪除的陣列
* use: removeDuplicates(books)
*/
function removeDuplicates(arr) {
const result = [];
const duplicatesIndices = [];
// 迴圈遍歷原始陣列中的每個專案
arr.forEach((current, index) => {
if (duplicatesIndices.includes(index)) return;
result.push(current);
// 在當前項之後迴圈遍歷陣列中的其他項
for (
let comparisonIndex = index + 1;
comparisonIndex < arr.length;
comparisonIndex++
) {
const comparison = arr[comparisonIndex];
const currentKeys = Object.keys(current);
const comparisonKeys = Object.keys(comparison);
// 檢查物件中的鍵數
if (currentKeys.length !== comparisonKeys.length) continue;
// 檢查鍵名
const currentKeysString = currentKeys.sort().join("").toLowerCase();
const comparisonKeysString = comparisonKeys.sort().join("").toLowerCase();
if (currentKeysString !== comparisonKeysString) continue;
// 檢查值
let valuesEqual = true;
for (let i = 0; i < currentKeys.length; i++) {
const key = currentKeys[i];
if (current[key] !== comparison[key]) {
valuesEqual = false;
break;
}
}
if (valuesEqual) duplicatesIndices.push(comparisonIndex);
} // end for loop
}); // end arr.forEach()
return result;
}
Recursion
/** 基礎示例 */
/**
* 遞減
* @param {*} num 外部傳入的引數
* use: countdown(5)
*/
const countdown = (num) => {
console.log(num);
num < 1 ? num : countdown(num - 1);
};
/**
* 遞迴 x 的 n 次方
* @param {*} x
* @param {*} n
* return:x的n次方結果
* use: pow(3, 6)
*/
/* 三元運算子簡寫以上程式碼塊 */
const pow = (x, n) => {
// n == 1 遞迴的基礎 。遞迴步驟:根據基礎的結果,決定是輸出結果還是再執行一遍函式
return n == 1 ? x : x * pow(x, n - 1);
};
/** 遞迴計算不同部門的工資 2019.08.08 */
// 物件陣列
const company = {
sales: [
{
name: "Asura",
salary: 1000,
},
{
name: "Satya",
salary: 600,
},
],
development: {
sites: [
{
name: "Buddha",
salary: 2000,
},
{
name: "Shakya",
salary: 1800,
},
],
internals: [
{
name: "Lokavit",
salary: 1300,
},
],
},
};
/**
* 用來完成作業的函式 遞迴計算不同部門的工資 2019.08.08
* @param {*} department 部門
* use: sumSalaries(company)
*/
function sumSalaries(department) {
// 如果傳入的是陣列
if (Array.isArray(department)) {
// 情況 (1) 求陣列的和
return department.reduce((prev, current) => prev + current.salary, 0);
} else {
// 情況 (2)
let sum = 0;
// 迭代物件中的 values 屬性值 ,每個values則是一個數組
for (let subdep of Object.values(department)) {
sum += sumSalaries(subdep); // 遞迴呼叫子部門,對結果求和
}
return sum;
}
}
/**
* 遞迴刪除深層陣列物件中某資料 2019.10.12
* 遞迴新增深層陣列物件中某資料 2019.10.12
*/
/** 物件陣列 */
const tableData = {
entry: "abc",
children: [
{
entry: "abc-bcd",
children: [
{
entry: "abc-bcd-cde",
},
{
entry: "abc-bcd-def",
},
],
},
{
entry: "abc-zxc",
children: [
{
entry: "abc-zxc-xcv",
},
{
entry: "abc-zxc-cvb",
},
],
},
],
};
/**
* 遞迴刪除深層陣列物件中某資料 2019.10.12
* data:傳入需遞迴的大陣列
* target:需要刪除的指定值
* use: this.recursiveDelete(this.tableData,row.entry)
*/
function recursiveDelete(data, target) {
if (!data) return;
if (!Array.isArray(data)) return;
for (let i = 0; i < data.length; i++) {
// 如果當前的[entry] == target傳入值
if (data[i].entry == target) {
this.$delete(data, i); // 從檢視刪除該資料
// 呼叫刪除API [target] 為外部傳入值,亦為介面所需引數
deleteSystemCommoncodes(target);
return;
}
// 非以上情況,且data[i]有children且其長度>0
else {
if (data[i].children && data[i].children.length > 0) {
// 遞迴本函式,繼續尋找 target
this.recursiveDelete(data[i].children, target);
}
}
}
}
/**
* 遞迴新增深層陣列物件中某資料 2019.10.12
* data:傳入需遞迴的大陣列
* target:需要刪除的指定值
* use:this.recursivePost(this.tableData,this.form)
*/
function recursivePost(data, target) {
if (!data) return;
if (!Array.isArray(data)) return;
/** 需要考慮以下問題:
* 透過 target.parentEntry 判斷當前需新增的是根元素還是子元素
* 新增根元素資料:
* 直接新增資料:this.$set(data,data.length,target)
* 新增子元素,需先判斷待插入資料的物件中[hasElement:true]且是否有[children],
* 如果有,則插入為:this.$set(data,data.length,target)
* 如果沒有,則在插入資料之前,需改變待插入資料的
*/
/** 無父節點的資料,將[target]物件直接新增到傳入的[data]中 */
if (!target.parentEntry) {
this.$set(data, data.length, target);
// this.getSystemData(); // 呼叫一下請求,讓資料重新回來。似乎沒有什麼作用
return;
} else {
/** 有父節點的資料,即[target.parentEntry]有值的情況下
* 遍歷傳入陣列,從中找到某資料.entry == 傳入target.parentEntry
*/
for (let i = 0; i < data.length; i++) {
// 如果 某資料.entry == 傳入target.parentEntry
if (data[i].entry == target.parentEntry) {
/** 判斷該資料的[hasElement]是否有子元素
* 如果 [hasElement:false]即沒有子元素,則該資料一定沒有[children]
*/
if (!data[i].hasElement) {
data[i].hasElement = true; // 該資料的[hasElement:true]
data[i].children = new Array(); // 為該資料手動新增一個[children:[]]屬性
// 以上設定完畢後,使用this.$set將資料插入到children陣列中
this.$set(data[i].children, data[i].children.length, target);
return;
} else if (data[i].hasElement) {
/** 如果 [hasElement:ture]即已有子元素 */
/** 如果該資料沒有[children] 將其加上一個children的陣列 */
if (!data[i].children) data[i].children = new Array();
this.$set(data[i].children, data[i].children.length, target);
return;
}
} else {
console.log("沒找到entry == parentEntry");
// 如果某條資料有 children,並且 長度>=0
if (data[i].children && data[i].children.length >= 0) {
// 遞迴本函式,直至資料成功插入整體資料的對應層級樹中
this.recursivePost(data[i].children, target);
}
}
}
}
}