我有一個深度嵌套的資料結構,我有興趣匹配我的陣列(和陣列的陣列)中的某個值,然后將一些資料推送到一個隨附的陣列中。例如,以下是我的顏色陣列,伴隨的是一個moreColors陣列,它可能存在也可能不存在:
var myData = [{
"color": "green",
"moreColors": [
{
"color": "beige"
},
{
"color": "black",
"moreColor": [
{
"color": "grey"
},
{
"color": "white",
"moreColors": [...]
}
]
}
]
}]
我有興趣在我的陣列中搜索顏色值gray并為該物件添加一個 moreColors 陣列moreColors: [{"color" : "blue"}]
。在某些情況下,如果陣列已經存在,這可能會使用push()方法。我將如何最好地實作這一目標?我的目標是我想在此處添加值并更新/更改myData陣列,因為這將傳遞給另一個函式。這里的嵌套可以有好幾級,因此回圈內的簡單回圈將不起作用。遞回函式在這里效果最好嗎?我也愿意接受更好的方法或使用像underscore或lodash這樣的庫。雖然我更喜歡香草 js 版本。下面是我開始的遞回解決方案,但是代碼不會運行超過一個級別。
findNested(myData, "grey")
function findNested(myArray, color) {
myArray.moreColors?.forEach(element => {
if(element.color !== color){
if(element.moreColors.length > 0) {
findNested(element.moreColors, color);
}
} else {
element.moreColors.push({
"color": "blue"
});
}
});
}
uj5u.com熱心網友回復:
這是我認為您正在嘗試的一個簡單示例。
findNestedColorObject()
接受要搜索的陣列和顏色字串,并回傳其color
屬性匹配的第一個物件。
updateMoreColors()
接受從上面回傳的物件,moreColors
如果它不存在則首先分配,然后推送到陣列。
function findNestedColorObject(array, color) {
let colorObject;
for (const obj of array) {
if (obj.color === color) {
colorObject = obj;
break;
}
if (obj.moreColors !== undefined) {
colorObject = findNestedColorObject(obj.moreColors, color);
}
}
return colorObject;
}
function updateMoreColors(colorObject, colors) {
colorObject.moreColors ??= [];
for (const color of [].concat(colors)) {
colorObject.moreColors.push({ color });
}
}
const myData = [{ "color": "green", "moreColors": [{ "color": "beige" }, { "color": "black", "moreColors": [{ "color": "grey" }, { "color": "white", "moreColors": ["ochre"] }] }] }];
const greyObject = findNestedColorObject(myData, 'grey');
console.log('found:')
console.log(greyObject);
updateMoreColors(greyObject, 'purple');
console.log('updated:');
console.log(greyObject);
const beigeObject = findNestedColorObject(myData, 'beige');
console.log('found:')
console.log(beigeObject);
updateMoreColors(beigeObject, ['salmon', 'crimson']);
console.log('updated:');
console.log(beigeObject);
或者,由于您的嘗試似乎是在同一個函式中搜索和更新,您可以將上面的兩個函式結合起來。(這將繼續更新所有匹配的物件,而不僅僅是第一個)。
function updateNestedColorObject(array, color, moreColors) {
for (const obj of array) {
if (obj.color === color) {
obj.moreColors ??= [];
for (const color of [].concat(moreColors)) {
obj.moreColors.push({ color });
}
}
if (obj.moreColors !== undefined) {
updateNestedColorObject(obj.moreColors, color, moreColors);
}
}
}
const myData = [{ "color": "green", "moreColors": [{ "color": "beige" }, { "color": "black", "moreColors": [{ "color": "grey" }, { "color": "white", "moreColors": ["ochre"] }] }] }];
updateNestedColorObject(myData, 'grey', 'purple');
updateNestedColorObject(myData, 'purple', 'beige');
updateNestedColorObject(myData, 'beige', ['salmon', 'crimson']);
console.log(myData);
uj5u.com熱心網友回復:
對不起,我不會讓自己沉入深淵。我不會幫你做像改變你的原始資料這樣野蠻的事情。
但是,如果您對從舊版本中創建新結構的版本感興趣,并且在適當的位置添加了額外的顏色節點,我們可以撰寫一個相當簡單的遞回:
const addColor = (target, newColor) => (xs) =>
xs .map (({color, moreColors = []}) => ({
color,
... (color == target
? {moreColors: addColor (target, newColor) (moreColors) .concat ({color: newColor})}
: moreColors .length > 0
? {moreColors: addColor (target, newColor) (moreColors)}
: {}
)
}))
const myData = [{color: "green", moreColors: [{color: "beige"}, {color: "black", moreColors: [{color: "grey"}, {color: "white", moreColors: [{color: "..."}]}]}]}]
console .log (addColor ('grey', 'blue') (myData))
// console .log (myData) // uncomment to see that the original has not been folded, spindled, or mutilated
.as-console-wrapper {max-height: 100% !important; top: 0}
我們映射陣列,保持顏色屬性不變,然后moreColors
以三種方式之一處理:
- 如果
color
匹配我們的目標顏色,我們在節點上重復moreColors
,并將我們的附加顏色附加到它。(如果此節點丟失,我們將其默認為空陣列。) - 如果沒有,并且我們有現有
moreColor
條目,我們會重復它們 - 如果我們沒有,我們將
moreColor
完全跳過該節點。
uj5u.com熱心網友回復:
嗨,檢查一下我剛剛制作的這個函式,它真的很短:) 編輯:我找到了一種更好的方法,它不會洗掉資料但回傳排序的 OBJ/OR 陣列(您可以將任何一個傳遞給此函式進行排序)請提供反饋
var myData = [{
"color": "green",
"moreColors": [
{
"color": "blue"
},
{
"color": "blue",
"moreColor": [
{
"color": "blue"
},
{
"color": "blue",
"moreColors": []
}
]
}
]
},['blue'],"blue"]
function searchArrOrObj(objOrArray,color,newColor) {
let arrayOrObj = Object.assign((objOrArray.constructor===Array?[]:{}), objOrArray)
for (item in arrayOrObj) {
if (arrayOrObj[item]===color) {
arrayOrObj[item] = newColor;
} else if (typeof arrayOrObj[item]==='object') {
arrayOrObj[item] = searchArrOrObj(arrayOrObj[item],color,newColor)
}
}
return arrayOrObj;
}
let newData = searchArrOrObj(myData,"blue","red")
console.log(myData)
console.log(newData)
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/470060.html
標籤:javascript 数组 递归 罗达什 下划线.js