Vis*_*eth 113 javascript lodash
我想知道在lodash中是否有一个更简单的方法来替换JavaScript集合中的项目?(可能重复,但我不明白那里的答案:)
我看了他们的文档但找不到任何东西
我的代码是:
var arr = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
// Can following code be reduced to something like _.XX(arr, {id:1}, {id:1, name: "New Name"});
_.each(arr, function(a, idx){
if(a.id === 1){
arr[idx] = {id:1, name: "Person New Name"};
return false;
}
});
_.each(arr, function(a){
document.write(a.name);
});
Run Code Online (Sandbox Code Playgroud)
更新: 我正在尝试替换的对象有许多属性,如
{id:1,Prop1:...,Prop2:...,依此类推}
解:
感谢dfsq,但我在lodash中找到了一个合适的解决方案,似乎工作正常并且非常整洁,我把它放在mixin中,因为我在很多地方都有这个要求.JSBin
var update = function(arr, key, newval) {
var match = _.find(arr, key);
if(match)
_.merge(match, newval);
else
arr.push(newval);
};
_.mixin({ '$update': update });
var arr = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
_.$update(arr, {id:1}, {id:1, name: "New Val"});
document.write(JSON.stringify(arr));
Run Code Online (Sandbox Code Playgroud)
更快的解决方案 正如@dfsq所指出的,以下方法更快
var upsert = function (arr, key, newval) {
var match = _.find(arr, key);
if(match){
var index = _.indexOf(arr, _.find(arr, key));
arr.splice(index, 1, newval);
} else {
arr.push(newval);
}
};
Run Code Online (Sandbox Code Playgroud)
dfs*_*fsq 170
在您的情况下,您需要做的就是在数组中查找对象并使用Array.prototype.splice
方法:
var arr = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
// Find item index using _.findIndex (thanks @AJ Richardson for comment)
var index = _.findIndex(arr, {id: 1});
// Replace item at index using native splice
arr.splice(index, 1, {id: 100, name: 'New object.'});
// "console.log" result
document.write(JSON.stringify( arr ));
Run Code Online (Sandbox Code Playgroud)
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
Run Code Online (Sandbox Code Playgroud)
小智 26
似乎最简单的解决方案是使用ES6 .map
或lodash _.map
:
var arr = [{id: 1, name: "Person 1"}, {id: 2, name: "Person 2"}];
// lodash
var newArr = _.map(arr, function(a) {
return a.id === 1 ? {id: 1, name: "Person New Name"} : a;
});
// ES6
var newArr = arr.map(function(a) {
return a.id === 1 ? {id: 1, name: "Person New Name"} : a;
});
Run Code Online (Sandbox Code Playgroud)
这具有避免改变原始数组的良好效果.
evi*_*ive 21
function findAndReplace(arr, find, replace) {
let i;
for(i=0; i < arr.length && arr[i].id != find.id; i++) {}
i < arr.length ? arr[i] = replace : arr.push(replace);
}
Run Code Online (Sandbox Code Playgroud)
现在让我们测试所有方法的性能:
// TC's first approach
function first(arr, a, b) {
_.each(arr, function (x, idx) {
if (x.id === a.id) {
arr[idx] = b;
return false;
}
});
}
// solution with merge
function second(arr, a, b) {
const match = _.find(arr, a);
if (match) {
_.merge(match, b);
} else {
arr.push(b);
}
}
// most voted solution
function third(arr, a, b) {
const match = _.find(arr, a);
if (match) {
var index = _.indexOf(arr, _.find(arr, a));
arr.splice(index, 1, b);
} else {
arr.push(b);
}
}
// my approach
function fourth(arr, a, b){
let l;
for(l=0; l < arr.length && arr[l].id != a.id; l++) {}
l < arr.length ? arr[l] = b : arr.push(b);
}
function test(fn, times, el) {
const arr = [], size = 250;
for (let i = 0; i < size; i++) {
arr[i] = {id: i, name: `name_${i}`, test: "test"};
}
let start = Date.now();
_.times(times, () => {
const id = Math.round(Math.random() * size);
const a = {id};
const b = {id, name: `${id}_name`};
fn(arr, a, b);
});
el.innerHTML = Date.now() - start;
}
test(first, 1e5, document.getElementById("first"));
test(second, 1e5, document.getElementById("second"));
test(third, 1e5, document.getElementById("third"));
test(fourth, 1e5, document.getElementById("fourth"));
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>
<div>
<ol>
<li><b id="first"></b> ms [TC's first approach]</li>
<li><b id="second"></b> ms [solution with merge]</li>
<li><b id="third"></b> ms [most voted solution]</li>
<li><b id="fourth"></b> ms [my approach]</li>
</ol>
<div>
Run Code Online (Sandbox Code Playgroud)
小智 19
[ES6]此代码适用于我.
let result = array.map(item => item.id === updatedItem.id ? updatedItem : item)
Run Code Online (Sandbox Code Playgroud)
您还可以使用findIndex和pick来实现相同的结果:
var arr = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
var data = {id: 2, name: 'Person 2 (updated)'};
var index = _.findIndex(arr, _.pick(data, 'id'));
if( index !== -1) {
arr.splice(index, 1, data);
} else {
arr.push(data);
}
Run Code Online (Sandbox Code Playgroud)
小智 8
如果你只是想更换一个属性,lodash_.find
和_.set
应该足够:
var arr = [{id: 1, name: "Person 1"}, {id: 2, name: "Person 2"}];
_.set(_.find(arr, {id: 1}), 'name', 'New Person');
Run Code Online (Sandbox Code Playgroud)
随着时间的流逝,您应该采用一种更具功能性的方法,在这种方法中,您应该避免数据突变并编写小的,单一责任的函数。与ECMAScript 6个标准,你可以在JavaScript中享受函数式编程范式与所提供的map
,filter
和reduce
方法。您不需要其他破折号,下划线或其他可以执行大多数基本操作的内容。
下面,我提供了一些针对此问题的建议解决方案,以展示如何使用不同的语言功能来解决此问题:
使用ES6地图:
const replace = predicate => replacement => element =>
predicate(element) ? replacement : element
const arr = [ { id: 1, name: "Person 1" }, { id:2, name:"Person 2" } ];
const predicate = element => element.id === 1
const replacement = { id: 100, name: 'New object.' }
const result = arr.map(replace (predicate) (replacement))
console.log(result)
Run Code Online (Sandbox Code Playgroud)
递归版本-等效的映射:
const replace = predicate => replacement =>
{
const traverse = ([head, ...tail]) =>
head
? [predicate(head) ? replacement : head, ...tail]
: []
return traverse
}
const arr = [ { id: 1, name: "Person 1" }, { id:2, name:"Person 2" } ];
const predicate = element => element.id === 1
const replacement = { id: 100, name: 'New object.' }
const result = replace (predicate) (replacement) (arr)
console.log(result)
Run Code Online (Sandbox Code Playgroud)
当最终数组的顺序不重要时,可以将其object
用作HashMap数据结构。如果您已经将键集合用作,则非常方便object
-否则,您必须先更改表示形式。
需要对象剩余散布,计算的属性名称和Object.entries。
const replace = key => ({id, ...values}) => hashMap =>
({
...hashMap, //original HashMap
[key]: undefined, //delete the replaced value
[id]: values //assign replacement
})
// HashMap <-> array conversion
const toHashMapById = array =>
array.reduce(
(acc, { id, ...values }) =>
({ ...acc, [id]: values })
, {})
const toArrayById = hashMap =>
Object.entries(hashMap)
.filter( // filter out undefined values
([_, value]) => value
)
.map(
([id, values]) => ({ id, ...values })
)
const arr = [ { id: 1, name: "Person 1" }, { id:2, name:"Person 2" } ];
const replaceKey = 1
const replacement = { id: 100, name: 'New object.' }
// Create a HashMap from the array, treating id properties as keys
const hashMap = toHashMapById(arr)
console.log(hashMap)
// Result of replacement - notice an undefined value for replaced key
const resultHashMap = replace (replaceKey) (replacement) (hashMap)
console.log(resultHashMap)
// Final result of conversion from the HashMap to an array
const result = toArrayById (resultHashMap)
console.log(result)
Run Code Online (Sandbox Code Playgroud)
也遇到了这个,并简单地这样做了。
const persons = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
const updatedPerson = {id: 1, name: "new Person Name"}
const updatedPersons = persons.map(person => (
person.id === updated.id
? updatedPerson
: person
))
Run Code Online (Sandbox Code Playgroud)
如果需要的话我们可以概括它
const replaceWhere = (list, predicate, replacement) => {
return list.map(item => predicate(item) ? replacement : item)
}
replaceWhere(persons, person => person.id === updatedPerson.id, updatedPerson)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
112400 次 |
最近记录: |