공식 문서가 말한 내용은 다음과 같습니다.
updateIn(keyPath: Array<any>, updater: (value: any) => any): List<T>
updateIn(keyPath: Array<any>, notSetValue: any, updater: (value: any) => any): List<T>
updateIn(keyPath: Iterable<any, any>, updater: (value: any) => any): List<T>
updateIn(keyPath: Iterable<any, any>, notSetValue: any, updater: (value: any) => any): List<T>
정상적인 웹 개발자 (기능 프로그래머가 아님)가 그것을 이해할 수있는 방법은 없습니다!
비 기능적 접근법의 경우 매우 간단합니다.
var arr = [];
arr.push({id: 1, name: "first", count: 2});
arr.push({id: 2, name: "second", count: 1});
arr.push({id: 3, name: "third", count: 2});
arr.push({id: 4, name: "fourth", count: 1});
var list = Immutable.List.of(arr);
list
이름이 세 번째 인 요소 의 개수 가 4로 설정된 위치를 어떻게 업데이트 합니까?
답변
가장 적절한 경우는 방법 findIndex
과 update
방법을 모두 사용 하는 것입니다.
list = list.update(
list.findIndex(function(item) {
return item.get("name") === "third";
}), function(item) {
return item.set("count", 4);
}
);
추신 : 항상지도를 사용할 수있는 것은 아닙니다. 예를 들어 이름이 고유하지 않고 같은 이름으로 모든 항목을 업데이트하고 싶습니다.
답변
.setIn () 을 사용하면 다음과 같은 작업을 수행 할 수 있습니다.
let obj = fromJS({
elem: [
{id: 1, name: "first", count: 2},
{id: 2, name: "second", count: 1},
{id: 3, name: "third", count: 2},
{id: 4, name: "fourth", count: 1}
]
});
obj = obj.setIn(['elem', 3, 'count'], 4);
항목의 색인을 모르면 업데이트하려고합니다. .findIndex () 사용하여 쉽게 찾을 수 있습니다 .
const indexOfListToUpdate = obj.get('elem').findIndex(listItem => {
return listItem.get('name') === 'third';
});
obj = obj.setIn(['elem', indexOfListingToUpdate, 'count'], 4);
그것이 도움이되기를 바랍니다!
답변
var index = list.findIndex(item => item.name === "three")
list = list.setIn([index, "count"], 4)
설명
Immutable.js 컬렉션을 업데이트하면 항상 원래 버전을 그대로 유지 한 채 해당 컬렉션의 새 버전이 반환됩니다. 그 때문에 JavaScript를 사용할 수 없습니다list[2].count = 4
돌연변이 구문을 . 대신 Java 콜렉션 클래스와 마찬가지로 메소드를 호출해야합니다.
더 간단한 예부터 시작해 봅시다.리스트의 개수 만 있습니다.
var arr = [];
arr.push(2);
arr.push(1);
arr.push(2);
arr.push(1);
var counts = Immutable.List.of(arr);
이제 세 번째 항목을 업데이트하려는 경우 일반 JS 배열은 다음과 같습니다 counts[2] = 4
. 우리가 메소드를 호출하는 돌연변이, 그리고 필요를 사용할 수 없기 때문에, 대신에 우리가 사용할 수 있습니다 : counts.set(2, 4)
– 수단 값을 설정하는 것이 4
인덱스에서2
.
깊은 업데이트
당신이 준 예제는 중첩 된 데이터를 가지고 있습니다. 우리는 단지 사용할 수 없습니다set()
초기 컬렉션에는 .
Immutable.js 컬렉션에는 이름이 “In”으로 끝나는 메서드 모음이 있으므로 중첩 된 집합을 더 깊이 변경할 수 있습니다. 가장 일반적인 업데이트 방법에는 관련 “입력”방법이 있습니다. 예를 들어 대한 set
이setIn
. 이러한 “In”메소드는 색인 또는 키를 첫 번째 인수로 승인하는 대신 “키 경로”를 승인합니다. 키 경로는 업데이트하려는 값에 도달하는 방법을 보여주는 인덱스 또는 키 배열입니다.
예를 들어, 색인 2의 목록에서 항목을 업데이트 한 다음 해당 항목 내의 “count”키의 값을 업데이트하려고합니다. 따라서 핵심 경로는입니다 [2, "count"]
. setIn
메소드 의 두 번째 매개 변수는 다음 과 같이 작동 set
합니다.이 값은 우리가 거기에 넣고 싶은 새로운 값이므로 다음과 같습니다.
list = list.setIn([2, "count"], 4)
올바른 키 경로 찾기
한 단계 더 나아가서 실제로 이름이 “세” 인 항목을 세 번째 항목과 다른 항목으로 업데이트하고 싶다고 말했습니다 . 예를 들어 목록이 정렬되지 않았거나 “two”라는 항목이 이전에 제거 되었습니까? 즉, 먼저 올바른 키 경로를 실제로 알아야합니다. 이를 위해 우리는 findIndex()
메소드 를 사용할 수 있습니다 ( 어쨌든 Array # findIndex 와 거의 동일하게 작동합니다) ).
목록에서 업데이트하려는 항목이있는 인덱스를 찾았 으면 업데이트 할 값의 키 경로를 제공 할 수 있습니다.
var index = list.findIndex(item => item.name === "three")
list = list.setIn([index, "count"], 4)
NB : Set
vsUpdate
원래 질문에는 set 메소드가 아닌 업데이트 메소드가 언급되어 있습니다. 이 함수의 두 번째 인수 ()는 설명과 updater
다르므로 설명하겠습니다 set()
. 두 번째 인수 set()
는 원하는 새 값 이지만 두 번째 인수 는 이전 값을 허용하고 원하는 새 값을 반환 update()
하는 함수 입니다. 그런 다음 updateIn()
“In”변형은 update()
키 경로를 허용합니다.
예를 들어 카운트를로 설정하지 않고 기존 카운트 4
를 증가 시키는 예제의 변형을 원한다면 기존 값에 1을 더하는 함수를 제공 할 수 있습니다.
var index = list.findIndex(item => item.name === "three")
list = list.updateIn([index, "count"], value => value + 1)
답변
공식 문서는 다음과 같습니다.
updateIn
updateIn
중첩 구조에 대해서만 필요 합니다. 서명과 문서가 훨씬 간단한 update
메소드를 찾고 있습니다.
기존 값으로 updater를 호출하는 반환 값 또는 index가 설정되지 않은 경우 notSetValue를 반환하여 색인에 업데이트 된 값이있는 새 List를 반환합니다.
update(index: number, updater: (value: T) => T): List<T> update(index: number, notSetValue: T, updater: (value: T) => T): List<T>
하는 경우, AS Map::update
문서는 제안이다 ” 동일합니다 :list.set(index, updater(list.get(index, notSetValue)))
“.
이름이 “third”인 요소
그것은 목록이 작동하는 방식이 아닙니다. 업데이트하려는 요소의 색인을 알아야하거나 검색해야합니다.
이름이 세 번째 인 요소의 개수가 4로 설정된 목록을 어떻게 업데이트 할 수 있습니까?
이것은해야합니다 :
list = list.update(2, function(v) {
return {id: v.id, name: v.name, count: 4};
});
답변
사용 ) (.MAP
list = list.map(item =>
item.get("name") === "third" ? item.set("count", 4) : item
);
var arr = [];
arr.push({id: 1, name: "first", count: 2});
arr.push({id: 2, name: "second", count: 1});
arr.push({id: 3, name: "third", count: 2});
arr.push({id: 4, name: "fourth", count: 1});
var list = Immutable.fromJS(arr);
var newList = list.map(function(item) {
if(item.get("name") === "third") {
return item.set("count", 4);
} else {
return item;
}
});
console.log('newList', newList.toJS());
// More succinctly, using ES2015:
var newList2 = list.map(item =>
item.get("name") === "third" ? item.set("count", 4) : item
);
console.log('newList2', newList2.toJS());
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.1/immutable.js"></script>
답변
나는 thomastuts 웹 사이트 에서이 접근법을 정말로 좋아합니다 .
const book = fromJS({
title: 'Harry Potter & The Goblet of Fire',
isbn: '0439139600',
series: 'Harry Potter',
author: {
firstName: 'J.K.',
lastName: 'Rowling'
},
genres: [
'Crime',
'Fiction',
'Adventure',
],
storeListings: [
{storeId: 'amazon', price: 7.95},
{storeId: 'barnesnoble', price: 7.95},
{storeId: 'biblio', price: 4.99},
{storeId: 'bookdepository', price: 11.88},
]
});
const indexOfListingToUpdate = book.get('storeListings').findIndex(listing => {
return listing.get('storeId') === 'amazon';
});
const updatedBookState = book.setIn(['storeListings', indexOfListingToUpdate, 'price'], 6.80);
return state.set('book', updatedBookState);
답변
당신은 사용할 수 있습니다 map
:
list = list.map((item) => {
return item.get("name") === "third" ? item.set("count", 4) : item;
});
그러나 이것은 전체 컬렉션을 반복합니다.