স্থায়ীভাবে কোনও বস্তুর কোনও সম্পত্তি সরান


145

আমি রেডাক্স ব্যবহার করছি। আমার রিডুসারে আমি এই জাতীয় কোনও জিনিস থেকে কোনও সম্পত্তি সরিয়ে দেওয়ার চেষ্টা করছি:

const state = {
    a: '1',
    b: '2',
    c: {
       x: '42',
       y: '43'
    },
}

এবং আমি মূল অবস্থাটি পরিবর্তিত না করে এরকম কিছু পেতে চাই:

const newState = {
    a: '1',
    b: '2',
    c: {
       x: '42',
    },
}

আমি চেষ্টা করেছিলাম:

let newState = Object.assign({}, state);
delete newState.c.y

তবে কিছু কারণে, এটি উভয় রাজ্য থেকে সম্পত্তি মুছে দেয়।

আমাকে এটি করতে সাহায্য করতে পারে?


3
লক্ষ্য করুন Object.assignশুধুমাত্র একটি সৃষ্টি অগভীর কপি এর stateএবং সেইজন্য state.cএবং newState.cএকই ভাগ বস্তু নির্দেশ করবে। আপনি নতুন বস্তু থেকে নয় yবরং ভাগ করা বস্তু থেকে সম্পত্তি মুছতে চেষ্টা করেছেন । cnewState
আকসেলি পলান

উত্তর:


224

ডেস্ট্রাকচারিং অ্যাসাইনমেন্ট সিনট্যাক্স ব্যবহার সম্পর্কে কীভাবে ?

const original = {
  foo: 'bar',
  stack: 'overflow',
};

// If the name of the property to remove is constant
const { stack, ...withoutFirst } = original;
console.log(withoutFirst); // Will be { "foo": "bar" }

// If the name of the property to remove is from a variable
const key = 'stack'
const { [key]: value, ...withoutSecond } = original;
console.log(withoutSecond); // Will be { "foo": "bar" }

// To do a deep removal with property names from variables
const deep = {
  foo: 'bar',
  c: {
   x: 1,
   y: 2
  }
};

const parentKey = 'c';
const childKey = 'y';
// Remove the 'c' element from original
const { [parentKey]: parentValue, ...noChild } = deep;
// Remove the 'y' from the 'c' element
const { [childKey]: removedValue, ...childWithout } = parentValue;
// Merge back together
const withoutThird = { ...noChild, [parentKey]: childWithout };
console.log(withoutThird); // Will be { "foo": "bar", "c": { "x": 1 } }


3
অতিরিক্ত লাইব্রেরি ব্যতীত দুর্দান্ত, এস of ব্যবহার করুন এবং যথেষ্ট সহজ।
sbk201

সর্বাধিক মার্জিত সমাধান
দীর্ঘ.লুক

12
নিস! এটির সাথে যেতে এখানে একটি এসআইএল সহায়ক ফাংশন const deleteProperty = ({[key]: _, ...newObj}, key) => newObj;। ব্যবহার: deleteProperty({a:1, b:2}, "a");দেয়{b:2}
মাইক্রব্রিজ

সুপার বুদ্ধিমান, আমি এইটির জন্য দেরী করেছি, তবে আমার নতুন প্রিয়গুলির মধ্যে একটি
গ্যাভিন

1
নোট করুন যে গভীর অপসারণ উদাহরণটি deep['c']খালি থাকলে ক্রাশ হবে , সুতরাং সাধারণ ক্ষেত্রে, আপনি কীটির উপস্থিতির জন্য একটি চেক যোগ করতে চাইতে পারেন।
লরেন্ট এস

46

আমি ES5 অ্যারের পদ্ধতি খুঁজে filter, mapএবং reduceদরকারী কারণ তারা সবসময় নতুন অ্যারে বা বস্তু ফিরে যান। এই ক্ষেত্রে আমি Object.keysঅবজেক্টটির উপরে পুনরাবৃত্তি Array#reduceকরতে এবং এটিকে আবার কোনও বস্তুতে পরিণত করতে ব্যবহার করব ।

return Object.assign({}, state, {
    c: Object.keys(state.c).reduce((result, key) => {
        if (key !== 'y') {
            result[key] = state.c[key];
        }
        return result;
    }, {})
});

আইএমও পরিষ্কার করার জন্য আমার সামান্য পরিবর্তন নিয়ে চিমিং করা ... আপনাকে একাধিক বৈশিষ্ট্য বাদ দিতে দেয়। const omit = ['prop1', 'prop2'] ... যদি (omit.indexOf (কী) === -1) ফলাফল [কী] = state.c [কী] ফেরতের ফলাফল; ...
জোশ-সাচস

3
myObjectচাবি myKeyসরানো সহ একটি অনুলিপি পেতে সমপরিমাণ ES6 :Object.keys(myObject).reduce((acc, cur) => cur === myKey ? acc : {...acc, [cur]: myObject[cur]}, {})
ট্রান্সাঙ্গা করা হবে

38

আপনি লোডাশ লাইব্রেরি _.omit(object, [paths])থেকে ব্যবহার করতে পারেন

উদাহরণ উদাহরণস্বরূপ নেস্ট করা যেতে পারে: _.omit(object, ['key1.key2.key3'])


3
দুর্ভাগ্যক্রমে, _.omitগভীর বৈশিষ্ট্যগুলি (ওপি কী জিজ্ঞাসা করেছিল) মুছতে পারে না। omit-deep-lodashএই উদ্দেশ্যে মডিউল আছে ।
অ্যালেক্সএম

2
@ অ্যালেক্সএম যা বলছিল তা বন্ধ করে দেওয়া হচ্ছে। আমি এটি দরকারী হিসাবে খুঁজে পেয়েছি এবং এটি _.cloneDeep(obj)লড্যাশ থেকে আমাদের কাছে আরও উপযুক্ত হতে পারে । এটি সহজেই অবজেক্টটি অনুলিপি করে এবং তারপরে আপনি delete obj.[key]কীটি সরাতে কেবল js ব্যবহার করতে পারেন।
অ্যালেক্স জে

W / @AlexJ একমত, cloneDeep পুরোপুরি কাজ করে এবং ভাল হিসাবে আপনি এটি দিয়ে বিস্তার সিনট্যাক্স ব্যবহার করতে পারেন: ..._ cloneDeep (অঙ্গরাজ্য) Redux জন্য।
শন চেজ

32

কেবল ES6 অবজেক্টের ডেস্ট্রাকচারিং বৈশিষ্ট্যটি ব্যবহার করুন

const state = {
    c: {
       x: '42',
       y: '43'
    },
}

const { c: { y, ...c } } = state // generates a new 'c' without 'y'

console.log({...state, c }) // put the new c on a new state


8
const {y, ...c} = state.ccবাম দিকে দুটি থাকার চেয়ে কিছুটা পরিষ্কার হতে পারে ।
ডোজেন্টমেটার


3
নীচের উত্তর থেকে, যদি মুছে ফেলার জন্য আপনার পরিবর্তনশীল নামটি উল্লেখ করতে হয়: const name = 'c'তবে আপনি তা করতে পারেন const {[name]:deletedValue, ...newState} = stateতবে newStateআপনার রিডুসারে ফিরে আসতে পারেন । এটি শীর্ষ স্তরের কী মোছার জন্য
এফএফএফ

23

কারণ আপনি state.cঅন্য বস্তুর মানটি অনুলিপি করছেন । এবং সেই মানটি অন্য জাভাস্ক্রিপ্ট অবজেক্টের পয়েন্টার। সুতরাং, উভয় পয়েন্টার একই বস্তুর দিকে নির্দেশ করছে।

এটা চেষ্টা কর:

let newState = Object.assign({}, state);
console.log(newState == state); // false
console.log(newState.c == state.c); // true
newState.c = Object.assign({}, state.c);
console.log(newState.c == state.c); // now it is false
delete newState.c.y;

আপনি বস্তুর গভীর অনুলিপিও করতে পারেন। এই প্রশ্নটি দেখুন এবং আপনি আপনার জন্য ভাল কি পাবেন।


2
এটি একটি দুর্দান্ত উত্তর! state.cএটি একটি রেফারেন্স, এবং রেফারেন্সটি ঠিক ঠিক অনুলিপি করা হচ্ছে। রেডাক্স একটি নরমাল স্টেট শেপ চায়, যার অর্থ নেস্টিংয়ের সময় রেফারেন্সের পরিবর্তে আইডি ব্যবহার করা। : Redux ডক্স পরীক্ষা করে দেখুন redux.js.org/docs/recipes/reducers/NormalizingStateShape.html
Ziggy

17

এটি সম্পর্কে:

function removeByKey (myObj, deleteKey) {
  return Object.keys(myObj)
    .filter(key => key !== deleteKey)
    .reduce((result, current) => {
      result[current] = myObj[current];
      return result;
  }, {});
}

এটি মুছে ফেলা উচিত কীটি ফিল্টার করে তারপরে অবশিষ্ট কীগুলি এবং প্রাথমিক অবজেক্ট থেকে একটি নতুন অবজেক্ট তৈরি করে। এই ধারণাটি টাইলার ম্যাকজিনেসের দুর্দান্ত অ্যাক্সেস প্রোগ্রাম থেকে চুরি করা হয়েছে।

JSBin



9

আপনার ক্ষেত্রে কোনও বৈশিষ্ট্য আনসেট করতে আপনি অপ্রয়োজনীয় সহায়ক ব্যবহার করতে পারেন :

import update from 'immutability-helper';

const updatedState = update(state, {
  c: {
    $unset: ['y']
  }
});    

তাহলে কীভাবে প্রতিটি অ্যারে অবজেক্ট আইটেমের সমস্ত সম্পত্তি "y" মুছবেন?
সার্ভেন্ট

@ 5 সার্ভেন্ট আমি মনে করি এটি অন্য প্রশ্ন, তবে আমি আপনাকে অ্যারের মানচিত্র তৈরি করতে এবং প্রদত্ত যে কোনও সমাধান এখানে প্রয়োগ করার পরামর্শ দিচ্ছি
জাভিয়ের পি

8

2019 হিসাবে, অন্য বিকল্পটি হল Object.fromEntriesপদ্ধতিটি ব্যবহার করা । এটি পর্যায়ে পৌঁছেছে 4।

const newC = Object.fromEntries(
    Object.entries(state.c).filter(([key]) => key != 'y')
)
const newState = {...state, c: newC}

এটি সম্পর্কে দুর্দান্ত জিনিসটি হ'ল এটি পূর্ণসংখ্যার কীগুলি সুন্দরভাবে পরিচালনা করে।



3

আপনি যে সমস্যাটি করছেন তা হ'ল আপনি আপনার প্রাথমিক অবস্থার গভীর ক্লোনিং করছেন না। সুতরাং আপনার কাছে অগভীর অনুলিপি রয়েছে।

আপনি স্প্রেড অপারেটর ব্যবহার করতে পারেন

  const newState = { ...state, c: { ...state.c } };
  delete newState.c.y

বা আপনার একই কোড অনুসরণ করা

let newState = Object.assign({}, state, { c: Object.assign({}, state.c) });
delete newState.c.y

1

আমি সাধারণত ব্যবহার করি

Object.assign({}, existingState, {propToRemove: undefined})

আমি বুঝতে পারি এটি আসলে সম্পত্তিটি সরিয়ে দিচ্ছে না তবে প্রায় সমস্ত উদ্দেশ্যেই 1 এর কার্যত সমতুল্য। এর জন্য সিনট্যাক্সটি বিকল্পগুলির চেয়ে অনেক সহজ যা আমি মনে করি এটি বেশ ভাল ট্রেড অফ।

1 আপনি যদি hasOwnProperty()ব্যবহার করছেন তবে আপনার আরও জটিল সমাধানটি ব্যবহার করতে হবে।


1

আমি এই প্যাটার্নটি ব্যবহার করি

const newState = Object.assign({}, state);
      delete newState.show;
      return newState;

তবে বইতে আমি অন্য একটি প্যাটার্ন দেখেছি

return Object.assign({}, state, { name: undefined } )

দ্বিতীয়টি, কীটি সরিয়ে দেয় না। এটি কেবল এটি নির্ধারিত করে দেয়।
bman

1

ইউটিলিটি;))

const removeObjectField = (obj, field) => {

    // delete filter[selectName]; -> this mutates.
    const { [field]: remove, ...rest } = obj;

    return rest;
}

ক্রিয়া প্রকার

const MY_Y_REMOVE = 'MY_Y_REMOVE';

ক্রিয়া স্রষ্টা

const myYRemoveAction = (c, y) => {

    const result = removeObjectField(c, y);

        return dispatch =>
            dispatch({
                type: MY_Y_REMOVE,
                payload: result
            })
    }

হ্রাসকারক

export default (state ={}, action) => {
  switch (action.type) {
    case myActions.MY_Y_REMOVE || :
      return { ...state, c: action.payload };
    default:
      return state;
  }
};

0

ইতিমধ্যে কয়েকটি উত্তরে যেমন ইঙ্গিত দেওয়া হয়েছে, এটি কারণ আপনি কোনও নেস্টেড রাষ্ট্র সংশোধন করার চেষ্টা করছেন। এক স্তর আরও গভীর। একটি আঞ্চলিক সমাধান হ'ল xরাজ্য স্তরে একটি হ্রাসকারক যুক্ত করা :

const state = {
    a: '1',
    b: '2',
    c: {
       x: '42',
       y: '43'
    },
}

গভীর স্তর হ্রাসকারক

let newDeepState = Object.assign({}, state.c);
delete newDeepState.y;

আসল স্তরের হ্রাসকারী

let newState = Object.assign({}, state, {c: newDeepState});
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.