我试图通过路径表达式以不可变的方式从对象中的数组中删除元素/同时保留原始对象并只更改路径上更改的对象。
所以我尝试使用一些方法:
const doc = {a: ['a', 'b']};
const newDoc = removeAt('a[0]', doc);
执行后,newDoc是{a:[' b']};和doc保持不变。
我尝试使用lodash取得了一些成功,但它真的很糟糕我需要如何设置它。有谁知道如何删除'没有所有这些中间步骤的那个元素?
function removeAt(path, obj) {
const arrayPath = _.initial(_.toPath(path));
const arrayIndex = _.last(_.toPath(path));
const [array] = _.at(obj, [arrayPath]);
const newArray = _.concat(_.slice(array, 0, arrayIndex), _.slice(array, arrayIndex + 1));
const newObj = _.setWith(_.clone(obj), arrayPath, newArray, _.clone);
return newObj;
}
const doc = {
'stringList': ['a', 'b'],
'container': {
objectList: [{
a: 'a',
b: 'b'
}, {
c: 'c',
d: 'd'
}]
}
};
const path = 'container.objectList.[0]';
const newDoc = removeAt(path, doc);
console.log('old doc and new newDoc:', {
doc,
newDoc
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"></script>
&#13;
我的removeAt工作(并保持stringList包含相同的对象),但是复杂的方式..: - /我正在寻找一种更清晰的方法来删除这些内容。最可爱的是lodash,lodash fp或普通JS ;-)
使用不可变的方式,我的意思是我需要在源对象中进行任何更改,但是生成一个新的Object,其中删除条目的路径上的那些对象确实已更改。这样我就有尽可能少的新对象。我需要做出反应,以便快速检查是否有任何变化,以及是否需要重新绘制其中一部分的UI树,这应该简化为更改的部分。
答案 0 :(得分:0)
您可以尝试将lodash.remove与lodash.set
一起使用在您的情况下,您可以尝试执行类似
的操作const doc = {a: ['a', 'b']};
const newDoc = _.set(doc, 'a', _.remove(doc.a, (v,i) => i !== 0 ));
答案 1 :(得分:0)
我不知道lodash,但它显然有一个内置的get(obj, path)。 因此,如果您只是从数组中删除元素,则以下将获取该数组,然后通过其索引删除元素(不进行检查)。所有这些都没有改变源对象。
const doc = {
'stringList': ['a', 'b'],
'container': {
objectList: [{
a: 'a',
b: 'b'
}, {
c: 'c',
d: 'd'
}]
}
};
function removeElement(obj, pathToArr, index){
// I don't know of a better way to clone, according to flob, this doesn't play well with React
//const clone = JSON.parse(JSON.stringify(obj));
const clone = _.clone(obj);
const arr = _.get(clone, pathToArr);
arr.splice(index, 1);
return clone;
}
console.log(removeElement(doc, "container.objectList", 0));
答案 2 :(得分:0)
我会使用:
重写你的函数 _.cloneDeep
不要改变原始对象
_.unset
通过路径表达式
_.set
新的_.compact
ed数组
function removeAt(path, index, obj) {
var res = _.cloneDeep(obj);
_.unset(res, path+'['+index+']');
_.set(res, path, _.compact(_.get(res, path)));
return res;
}
const doc = {
'stringList': ['a', 'b'],
'container': {
objectList: [{
a: 'a',
b: 'b'
}, {
c: 'c',
d: 'd'
}]
}
};
const path = 'container.objectList';
const newDoc = removeAt(path, 0, doc);
console.log(doc, newDoc);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"></script>