简体   繁体   English

将值添加到具有基于数组的键深度的对象

[英]Add a value to an object with its key depth based on an array

I have an array. 我有一个数组。 Let's say it's: 可以说是:

const array = ["lvl1", "lvl2", "lvl3", "key"]

I have a value. 我有一个价值。 Let's say it's: 可以说是:

const value = false

I have an object. 我有一个对象。 Let's say it's: 可以说是:

const object = {
  lvl1: {
    dogs: "bark",
    lvl2: {
      cats: "meow",
      lvl3: {
        cows: "moo"
        key: true
      }
    }
  }
}

How do I create a function that takes in the array and value , then updates the object so that the key in the array (the last item in the array) is updated with the new value ? 如何创建一个接受arrayvalue ,然后更新对象,以便使用新value更新数组中的key (数组中的最后一项)? It needs to be nested appropriately based on the first array.length - 1 strings in the array. 需要根据第一个array.length - 1数组中的array.length - 1字符串适当地嵌套它。

For example, let's called the function createObject . 例如,我们将其称为函数createObject If I call it using the array and value already defined above as: 如果我使用上面已经定义为以下内容的arrayvalue来调用它:

const newObject = createObject(array, value)

Then newObject should be equal to: 那么newObject应该等于:

{
  lvl1: {
    dogs: "bark",
    lvl2: {
      cats: "meow",
      lvl3: {
        cows: "moo"
        key: false
      }
    }
  }
}

Here's another example with a different level of nesting: 这是另一个具有不同嵌套级别的示例:

const updatedObject = createObject(["lvl1", "lvl2", "cats"], "stink")

Then updatedObject should be equal to: 然后,updatedObject应该等于:

{
  lvl1: {
    dogs: "bark",
    lvl2: {
      cats: "stink",
      lvl3: {
        cows: "moo"
        key: true
      }
    }
  }
}

I've gotten this far but it's not working: 我已经走了这么远,但没有用:

import object from "./object"

const createObject = (array, value) => {
  let results = object;
  for (let i = 0; i < array.length; i++) {
    i === array.length - 1
      ? (results = results[array[i]] = {
          ...results[array[i]],
          [array[i]]: value
        })
      : (results = results[array[i]] = {
          ...results[array[i]],
          [results[array[i]]]: {}
        });
    }
  return results;
}

I don't want to change the initial object. 我不想更改初始对象。 I want to return a new object. 我想返回一个新对象。 And I won't be adding any new key/value pairs to the object, only changing existing key/value pairs. 而且我不会在对象上添加任何新的键/值对,而只会更改现有的键/值对。

This is a bit more generic because it doesn't assume the source is a global variable named object : 这有点通用,因为它不假定源是名为object的全局变量:

 let array = ["lvl1", "lvl2", "lvl3", "key"]; let value = false; let createObject = (keys, value) => { let o, obj = o = {}; let lastKey = keys.pop(); keys.forEach(key => o = o[key] = o[key] || {}); o[lastKey] = value; return obj; }; let addToObject = (obj, keys, value) => { let o, copy = o = JSON.parse(JSON.stringify(obj)); let lastKey = keys.pop(); keys.forEach(key => o = o[key] = o[key] || {}); o[lastKey] = value; return copy; }; let x = createObject(array, value); let y = addToObject(x, ['lvl1'], 3); let z = addToObject(y, ['a', 'b', 'c'], 4); console.log(x); console.log(y); console.log(z); 

You could take the entries and build new object and check if the actual key is equal to the first item of the array, then check the length of the rest array as well and take the value. 您可以获取条目并构建新对象,并检查实际键是否等于数组的第一项,然后还检查其余数组的长度并获取值。 For a nested copy take a check for an object and build a new deeper level by calling the function again. 对于嵌套副本,请检查对象,然后通过再次调用该函数来构建新的更深层次。

 function getObject(object, [key, ...keys], value) { return Object.assign({}, ...Object .entries(object) .map(([k, v ]) => ({ [k]: k === key && !keys.length ? value : v && typeof v === 'object' ? getObject(v, k === key ? keys : [], value) : v })), Object.keys(object).includes(key) || { [key]: keys.length ? getObject({}, keys, value) : value } ); } const object1 = { lvl1: { dogs: "bark", lvl2: { cats: "meow", lvl3: { cows: "moo", key: true } } } }, object2 = getObject(object1, ["lvl1", "lvl2", "lvl3", "key"], false), object3 = getObject(object2, ["lvl1", "lvl2", "cats"], "stink"), object4 = getObject({}, ["lvl1", "lvl2", "cats"], "stink");; console.log(object1); console.log(object2); console.log(object3); console.log(object4); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM