Como posso remover um elemento de uma lista com o lodash?

165

Eu tenho um objeto que se parece com isso:

var obj = {
    "objectiveDetailId": 285,
    "objectiveId": 29,
    "number": 1,
    "text": "x",
    "subTopics": [{
        "subTopicId": 1,
        "number": 1
    }, {
        "subTopicId": 2,
        "number": 32
    }, {
        "subTopicId": 3,
        "number": 22
    }]
}
var stToDelete = 2;

Eu lodashinstalei no meu aplicativo para outras coisas. Existe uma maneira eficiente lodashde excluir a entrada: {"subTopicId":2, "number":32}do objobjeto?

Ou existe uma maneira javascript para fazer isso?

Samantha JT Star
fonte
1
você pode simplesmente usar splice( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) para remover o item de uma lista
z33m
1
O título foi alterado porque a remoção de 4 de uma matriz [1,4,5] não pode ser feita dessa maneira. Sim, eu entendo que matrizes podem ser implementadas a partir do hash / objeto e provavelmente são, mas há uma diferença sutil nesses dois. Para remover de uma matriz, você usaria result = _.pull(arr, value) Isso removeria todos os valores correspondentes da lista.
usar o seguinte código

Respostas:

247

Como Lyyons apontou nos comentários, uma maneira mais idiomática e cansativa de fazer isso seria usar _.remove, assim:

_.remove(obj.subTopics, {
    subTopicId: stToDelete
});

Além disso, você pode passar uma função predicada cujo resultado será usado para determinar se o elemento atual deve ser removido ou não.

_.remove(obj.subTopics, function(currentObject) {
    return currentObject.subTopicId === stToDelete;
});

Como alternativa, você pode criar uma nova matriz filtrando a antiga _.filtere atribuí-la ao mesmo objeto, como este

obj.subTopics = _.filter(obj.subTopics, function(currentObject) {
    return currentObject.subTopicId !== stToDelete;
});

Ou

obj.subTopics = _.filter(obj.subTopics, {subTopicId: stToKeep});
thefourtheye
fonte
3
A razão pela qual essa resposta é boa é porque você pode usar uma função predicada , que é exatamente o que eu estava procurando. A remoção de um elemento é trivial se você conhece o índice, mas e quando você não o conhece?
random_user_name 19/01
3
Pode valer a pena mencionar _.filter se você não quer transformar a matriz original ....
random_user_name
@cale_b Obrigado :-) Atualizou a resposta com a _.filterversão.
thefourtheye
7
@thefourtheye _.filter retorna um elemento se o predicado for verdadeiro. Sua implementação vai devolver todos os elementos não desejados em vez daqueles que você quer manter
Xeltor
5
@ thefourtheye você deve usar em _.rejectvez de _.filterusar o mesmo predicado. Veja minha resposta para mais detalhes!
Xeltor
29

Basta usar JS vanilla. Você pode usar splicepara remover o elemento:

obj.subTopics.splice(1, 1);

Demo

Andy
fonte
3
o usuário pedeIs there an efficient way to use _lodash to delete
semirturgay
7
@ Andy Você está certo, mas e se o índice ainda não for conhecido?
thefourtheye
3
splice () é a melhor abordagem se você deseja que sua matriz seja mutada. Se você usar remove, ele retornará a nova matriz e isso deverá ser reatribuído.
omarjebari 21/09/18
Se você deseja remover um item de uma matriz por seu índice na matriz (obviamente, você tem esse índice se deseja executar a ação de remoção dessa maneira), usar o método de emenda é a maneira mais eficiente (e fácil) para fazer isso. Não há necessidade de comparar qualquer coisa e tornar o código mais complicado e vulnerável para bugs e erros ...
TheCuBeMan
26

você pode fazer isso com _pull.

_.pull(obj["subTopics"] , {"subTopicId":2, "number":32});

verifique a referência

semirurgião
fonte
7
De acordo com os documentos, _.pullusa igualdade estrita para comparações, ou seja, === . Dois objetos simples diferentes nunca serão comparados como iguais por ===(ou por ==esse assunto). Portanto, seu código acima nunca removerá nenhum elemento da matriz.
Mark Amery
1
No entanto, esse é o único que trabalha com cadeias de caracteres em matriz. _.removeapenas libera a matriz.
Yauheni Prakopchyk
3
Eu ainda acho que esta é a resposta certa. JS .filter remove todos os elementos correspondentes, JS .splice exige que eu conheça o índice, _.remove itera sobre todos os elementos da matriz, sendo menos eficiente. _.pull é exatamente o que eu quero: _.pull (array, itemToRemove).
Judah Gabriel Himango
21

Agora você pode usar _.reject, que permite filtrar com base no que você precisa se livrar, em vez do que você precisa manter.

diferente _.pullou _.removeque só funcionam em matrizes, ._rejectestá trabalhando em qualquer Collection

obj.subTopics = _.reject(obj.subTopics, (o) => {
  return o.number >= 32;
});
Xeltor
fonte
2

Existem quatro maneiras de fazer isso como eu sei

const array = [{id:1,name:'Jim'},{id:2,name:'Parker'}];
const toDelete = 1;

O primeiro:

_.reject(array, {id:toDelete})

O segundo é:

_.remove(array, {id:toDelete})

Dessa maneira, o array será alterado.

O terceiro é:

_.differenceBy(array,[{id:toDelete}],'id')
// If you can get remove item 
// _.differenceWith(array,[removeItem])

O último é:

_.filter(array,({id})=>id!==toDelete)

Estou aprendendo lodash

Responda para fazer um registro, para que eu possa encontrá-lo mais tarde.

mqliutie
fonte
Eu estava procurandoreject
Sampgun 14/01
2

Além da resposta @thefourtheye, usando o predicado em vez das funções anônimas tradicionais:

  _.remove(obj.subTopics, (currentObject) => {
        return currentObject.subTopicId === stToDelete;
    });

OU

obj.subTopics = _.filter(obj.subTopics, (currentObject) => {
    return currentObject.subTopicId !== stToDelete;
});
Pranav Singh
fonte
1

lodash e datilografado

const clearSubTopics = _.filter(obj.subTopics, topic => (!_.isEqual(topic.subTopicId, 2)));
console.log(clearSubTopics);
Uliana Pavelko
fonte
0

Aqui está a função lodash simples com array e excluindo-a com o número do índice.

index_tobe_delete = 1

fruit = [{a: "apple"}, {b: "banana"}, {c: "choco"}]
_.filter(fruit, (value, key)=> {
return (key !== index_tobe_delete)
})
Anupam Maurya
fonte