使用Lodash将元素推入对象中的任何位置

时间:2019-04-04 12:39:24

标签: javascript lodash

我正在使用lodash操纵JSON对象。我并不反对使用Vanilla JS,但是由于我目前正在研究PoC,因此我只是在寻找最快的测试解决方案。

这就是我面临的问题:我希望能够轻松地将元素push let dl = {}; customPush(dl, 'a.b', { c: 3, d: 4 }); // or customPush(dl, ['a', 'b'], { c: 3, d: 4 }); 放置在对象中任何位置的数组中,并且它应该自动创建所有丢失的节点,包括最后一个数组。 / p>

例如,假设我有一个空对象,并且我想创建一个函数,该函数可以使用正确的值填充我的对象,例如:

dl = {
  a: {
    b: [{
      c: 3,
      d: 4
    }]
  }
}

应创建:

function customPush(obj, path, item) {
  // This is just assign the item to the path, not pushing to a new array
  _.set(dl, path, item);

  // This one is not doing anything visible
  _.get(dl, path, []).push(item);

  // Pushing in this one doesn't work with a path like 'a.b'
  if (_.has(dl, path)) {
    dl.path.push(item);
  } else {
    _.set(dl, path, [item]);
  }

  // Any idea?
  ...
}

这是我尝试过的所有内容,但没有一个起作用:

   -- To hold the Account table data
   Declare @Accounts table (ID INT, ParentAccountID INT) 

   -- To be updated 
   Declare @AccountID       int = 4;
   Declare @ParentAccountID int = 7;

   Declare @NextParentAccountID INT = @ParentAccountID

   Declare @IsCircular int = 0

   INSERT INTO @Accounts values (1, NULL), (2,1), (3,1) ,(4,3), (5,4), (6,5), (7,6), (8,7)

   -- No circular reference value
   --Select * from @Accounts

   -- Request to update ParentAccountID to 7 for the Account ID 4
   update @Accounts  
   set ParentAccountID = @ParentAccountID
   where ID = @AccountID

   Select * from @Accounts

   WHILE(1=1)
   BEGIN            
       -- Take the ParentAccountID for @NextParentAccountID
       SELECT @NextParentAccountID = ParentAccountID from @Accounts WHERE ID = @NextParentAccountID  

       -- If the @NextParentAccountID is NULL, then it reaches the top level account, no circular reference hence break the loop 
       IF (@NextParentAccountID IS NULL) 
       BEGIN
        BREAK;
       END

       -- If the @NextParentAccountID is equal to @AccountID (to which the update was done) then its creating circular reference
       -- Then set the @IsCircular to 1 and break the loop
       IF (@NextParentAccountID = @AccountID ) 
       BEGIN
        SET @IsCircular = 1
        BREAK
       END
   END

IF @IsCircular = 1 
    BEGIN 
        select 'CircularReference' as 'ResponseCode'
    END

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

您在这里的尝试非常关闭:

// Pushing in this one doesn't work with a path like 'a.b'
if (_.has(dl, path)) {
  dl.path.push(item);
} else {
  _.set(dl, path, [item]);
}

如果仅存在数组,则只需要使用_.get,否则就需要使用_.set。您已经在做后一部分了。

function customPush(obj, path, item) {
  if (_.has(obj, path)) {
    let arr = _.get(obj, path);
    arr.push(item)
  } else {
    _.set(obj, path, [item]);
  }
}

let objOne = { }
let objTwo = { a: [] }

let objThree = { 
  a: {
    b: {
      c: {
      }
    }
  }
}

let objFour = {
  a: {
    b: {
      c: {
        d: []
      }
    }
  }
}

customPush(objOne, "a", "item");
console.log("objOne", objOne);

customPush(objTwo, "a", "item");
console.log("objTwo", objTwo);

customPush(objThree, "a.b.c.d", "item");
console.log("objThree", objThree);

customPush(objFour, "a.b.c.d", "item");
console.log("objFour", objFour);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>

值得一提的是,只有当键不存在或键其值为数组时,此方法才有效。如果将路径提供给具有非数组值的现有键,则会出现错误。您可以使用_.isArray进行检查,但是如果某个键存在并且不保存数组,我不确定该怎么做。