簡體   English   中英

將數組轉為更深層次的對象

[英]Turn array to a deep level of object

我有一個數組和一個這樣的示例對象:

const array = ['a', 'b.c', 'c.d.e']

樣本

const sample = {
  'aa': 'test',
  'a': 'value',
  'b': {
    'c': 'value'
  },
  'c': {
    'd': {
      'e': 'value'
    }
  },
  'e': {
    'f': {
      'g': {
        'h' : 'value'
      }
    }
  }
}

然后我想根據樣本制作一個新對象。 結果應如下所示:

const newSample = {
  'aa': 'test',
  'a': 'oldvalue' + 1,
  'b': {
    'c': 'oldvalue' + 1
  },
  'c': {
    'd': {
      'e': 'oldvalue' + 1
    }
  },
  'e': {
    'f': {
      'g': {
        'h' : 'oldvalue'
      }
    }
  }
}

我正在考慮遍歷數組並計算每個元素的長度。 但是,它不如數組和樣本的級別增加那么有效。 有沒有可以做得更好的算法?

 const array = ['a', 'b.c', 'cde'] const sample = { 'aa': test, 'a': 'value', 'b': { 'c': 'value' }, 'c': { 'd': { 'e': 'value' } }, 'e': { 'f': { 'g': { 'h' : 'value' } } } } const newSample = {} const transformer = (array) => { array.forEach(item => { const itemArr = item.split('.') if (itemArr.length === 1) { console.log(sample[itemArr[0]]) newSample[itemArr[0]] = sample[itemArr[0]] + 1 } // the condition goes on... }) } transformer(array) console.log(newSample)

謝謝,

您可以減少拆分的鍵並使用最后一個鍵保存分配的最后一個鍵。

 const keys = ['a', 'b.c', 'cde'] object = { a: 'value', b: { c: 'value' }, c: { d: { e: 'value' } }, e: { f: { g: { h : 'value' } } } }, transformer = (objec, keys) => keys.reduce((r, s) => { var path = s.split('.'), last = path.pop(), final = path.reduce((o, k) => o[k] = o[k] || {}, r); final[last] = (final[last] || '') + 1; // or whatever you need change return r; }, object); console.log(transformer(object, keys));
 .as-console-wrapper { max-height: 100% !important; top: 0; }

通過返回具有更改值的深層副本來實現非變異方法。

 function transformer(object, keys) { return Object.entries(object).reduce((r, [k, v]) => { r[k] = v && typeof v === 'object' ? transformer(v, keys.filter(s => s.startsWith(k + '.')).map(s => s.split('.').slice(1).join('.'))) : keys.includes(k) ? (v || '') + 1: v; return r; }, {}); } const keys = ['a', 'b.c', 'cde'] object = { a: 'value', b: { c: 'value' }, c: { d: { e: 'value' } }, e: { f: { g: { h : 'value' } } } }; console.log(transformer(object, keys));
 .as-console-wrapper { max-height: 100% !important; top: 0; }

看起來您只想將新值應用於一組范圍字段。

您可以遍歷所需的范圍字段並為它們設置一個新值。 以下問題的答案: 將點表示法中的 JavaScript 字符串轉換為對象引用非常適合此問題集。

警告

如果您需要深度復制或克隆對象,您可以對其進行序列化-反序列化:

function cloneObject(obj) {
  return JSON.parse(JSON.stringify(obj));
}

普通分配處理深副本:

function cloneObject(obj) {
  return Object.assign({}, obj);
}

 const array = ['a', 'b.c', 'cde', 'efgh']; const sample = { 'a': 'value', 'b': { 'c': 'value' }, 'c': { 'd': { 'e': 'value' } }, 'e': { 'f': { 'g': { 'h': 'value' } } } }; const newSample = setValueForKeys(cloneObject(sample), array, 'someValue'); console.log('Updated:', newSample); console.log('Original:', sample); function setValueForKeys(source, keys, value) { keys.forEach((key) => index(source, key, value)); return source; } function cloneObject(obj) { return JSON.parse(JSON.stringify(obj)); } // See: https://stackoverflow.com/a/6394168/1762224 function index(obj, is, value) { if (typeof is == 'string') return index(obj, is.split('.'), value); else if (is.length == 1 && value !== undefined) return obj[is[0]] = value; else if (is.length == 0) return obj; else return index(obj[is[0]], is.slice(1), value); } function multiIndex(obj, is) { return is.length ? multiIndex(obj[is[0]], is.slice(1)) : obj; } function pathIndex(obj, is) { return multiIndex(obj, is.split('.')) }
 .as-console-wrapper { top: 0; max-height: 100% !important; }

您可以使用forEach循環來循環數組中的每個元素,然后split每個路徑split為數組,然后在該路徑數組上使用reduce方法來更新每個嵌套屬性。

 const array = ['a', 'b.c', 'cde'] const sample = {"a":"value","b":{"c":"value"},"c":{"d":{"e":"value"}},"e":{"f":{"g":{"h":"value"}}}} function update(array, sample) { array.forEach(c => { c.split('.').reduce((r, e, i, a) => { if (!a[i + 1]) r[e] = r[e] + 1 else return r[e] || {} }, sample) }) } update(array, sample); console.log(sample)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM