রূপান্তর ছাড়াই অবজেক্ট থেকে মান সরিয়ে ফেলুন


102

আসল অবজেক্টটি রূপান্তর না করে নির্দিষ্ট কীতে কোনও অবজেক্ট থেকে কোনও মান মুছে ফেলার একটি উত্তম এবং স্বল্প উপায় কী?

আমি কিছু করতে চাই:

let o = {firstname: 'Jane', lastname: 'Doe'};
let o2 = doSomething(o, 'lastname');
console.log(o.lastname); // 'Doe'
console.log(o2.lastname); // undefined

আমি জানি যে এই জাতীয় কাজের জন্য প্রচুর অপরিবর্তনীয় লাইব্রেরি রয়েছে তবে আমি লাইব্রেরি ছাড়াই চলে যেতে চাই। তবে এটি করার জন্য, একটি প্রয়োজনীয়তাটি হ'ল একটি সহজ এবং স্বল্প উপায় যা কোনও ইউটিলিটি ফাংশন হিসাবে পদ্ধতিটিকে বিমূর্ত না করে কোনও কোড জুড়ে ব্যবহার করা যায়।

যেমন একটি মান যুক্ত করার জন্য আমি নিম্নলিখিতটি করি:

let o2 = {...o1, age: 31};

এটি বেশ সংক্ষিপ্ত, মনে রাখা সহজ এবং কোনও ইউটিলিটি ফাংশনের প্রয়োজন নেই।

কোনও মান অপসারণের জন্য কি এরকম কিছু আছে? ES6 খুব স্বাগত।

আপনাকে অনেক ধন্যবাদ!


"অবজেক্টটিকে রূপান্তর না করে একটি মান সরিয়ে ফেলুন" এর কোনও মানে নেই। আপনি কোনও কিছু থেকে সরাতে এবং একই সাথে অক্ষত রাখতে পারবেন না। আপনি আসলে যা করছেন তা আংশিক অনুলিপি করা।
জেজেজে

উত্তর:


226

হালনাগাদ:

আপনি একটি ছদ্মবেশী ডেস্ট্রাকচারিং অ্যাসাইনমেন্ট সহ কোনও বস্তু থেকে কোনও সম্পত্তি সরিয়ে ফেলতে পারেন :

const doSomething = (obj, prop) => {
  let {[prop]: omit, ...res} = obj
  return res
}

যদিও, আপনি যে সম্পত্তির নামটি মুছে ফেলতে চান তা স্থিতিশীল হলেও, আপনি এটি একটি সাধারণ ওলাইনার দিয়ে মুছে ফেলতে পারেন:

let {lastname, ...o2} = o

সবচেয়ে সহজ উপায় সহজ উপায় বা আপনি নিজের অবজেক্টটিকে রূপান্তর করার আগে ক্লোন করতে পারেন:

const doSomething = (obj, prop) => {
  let res = Object.assign({}, obj)
  delete res[prop]
  return res
}

বিকল্পভাবে আপনি ইউটিলিটি লাইব্রেরি omitথেকে ফাংশনটিlodash ব্যবহার করতে পারেন :

let o2 = _.omit(o, 'lastname')

এটি লোডাশ প্যাকেজের অংশ হিসাবে , বা স্ট্যান্ড্যালোন লড্যাশ.মিট প্যাকেজ হিসাবে উপলব্ধ।


4
আসলেই কি এর সহজ সমাধান? যেমন অ্যারেগুলির জন্য আপনি a2 = a1.filter(el => el.id !== id)কোনও নির্দিষ্ট আইডির মাধ্যমে অ্যারের মধ্যে একটি উপাদান বাদ দিতে পারেন । কোনও জিনিসের জন্য কি এমন কোনও জিনিস নেই?
আমানন

4
আমি @ আমান এর সাথে একমত উভয় ক্ষেত্রেই সেখানে হয় ভাল সমাধান, অথবা ES6 সত্যিই একটি আরো কার্মিক ভাবে জাতীয় ব্যবহারযোগ্য উপার্জন সম্পর্কে কিছু মিস করেছি। যেমন রুবির রয়েছেkeep_if
আগস্টিন রিডিংগার

4
@ অগাস্টিনরিডিংগার আসলে একটি উপায় আছে। আমার আপডেট দেখুন।
লিওনিড বেসচাস্টনি

4
আপডেট করা ডেস্ট্রাকচারিং সলিউশন দুর্দান্ত। যদিও এতে আমার মন একটু উড়ে গেছে। const {[prop], ...rest} = objকাজ করবে না কেন ? কেন আপনাকে উত্তোলিত সম্পত্তিটি একটি নতুন ভেরিয়েবলের ( omitএই ক্ষেত্রে) অর্পণ করতে হবে ?
ব্রানওয়েব

4
@ অ্যান্টনি 4 আপনি আপনার no-unused-varsনিয়মে "বাদ দেওয়া" বা "বাদ দেওয়া" যুক্ত করতে পারেন , এটি কেবল রেজেক্স।
adrianmc

35

ES7 অবজেক্ট ডেস্ট্রাকচারিং সহ:

const myObject = {
  a: 1,
  b: 2,
  c: 3
};
const { a, ...noA } = myObject;
console.log(noA); // => { b: 2, c: 3 }

4
যদি aকোনও ভেরিয়েবলে সংরক্ষণ করা হয় const x = 'a'?
এফএফএফ

কিছুই পরিবর্তন করে না। একটি কেবল অ্যারের প্রথম উপাদানকে বোঝায়। এটি এর মতো হতে পারে: const { a,b, ...noA } = myObject; console.log(noA); // => {c: 3 }
সেনবোন

4
এটি সবচেয়ে মার্জিত, সহজ সমাধান
জো

4
কীগুলি সংখ্যা হলে এটি করার কোনও উপায় আছে?
মার্ক স্লোথ ইস্টম্যান


4

উপরের মন্তব্যে যেমন পরামর্শ দেওয়া হয়েছে আপনি যদি আপনার পছন্দ করতে চান তবে objectআমি একাধিক আইটেম অপসারণ করতে এটি প্রসারিত করতে চাইছি filter। এবংreduce

যেমন

    const o = {
      "firstname": "Jane",
      "lastname": "Doe",
      "middlename": "Kate",
      "age": 23,
      "_id": "599ad9f8ebe5183011f70835",
      "index": 0,
      "guid": "1dbb6a4e-f82d-4e32-bb4c-15ed783c70ca",
      "isActive": true,
      "balance": "$1,510.89",
      "picture": "http://placehold.it/32x32",
      "eyeColor": "green",
      "registered": "2014-08-17T09:21:18 -10:00",
      "tags": [
        "consequat",
        "ut",
        "qui",
        "nulla",
        "do",
        "sunt",
        "anim"
      ]
    };

    const removeItems = ['balance', 'picture', 'tags']
    console.log(formatObj(o, removeItems))

    function formatObj(obj, removeItems) {
      return {
        ...Object.keys(obj)
          .filter(item => !isInArray(item, removeItems))
          .reduce((newObj, item) => {
            return {
              ...newObj, [item]: obj[item]
            }
          }, {})
      }
    }

    function isInArray(value, array) {
      return array.indexOf(value) > -1;
    }


4
আপনি হ্রাসে ফিল্টার শর্তটি প্রয়োগ করেন না কেন তাই আপনি নিজের একটি লুপ সংরক্ষণ করতে পারেন?
ইভো সবদেব

@ আইভোসাবেভ টিপটির জন্য ধন্যবাদ আমার কোডে আমার কয়েকটি ফাংশন রয়েছে যেখানে আমি ফিল্টার করি তারপরে হ্রাস করি তবে লুপটি সংরক্ষণ করার জন্য আপনার পরামর্শটি এগিয়ে যাওয়ার বিষয়টি বিবেচনা করব।
ak85

4

পারফরম্যান্স আনতে কিছু মশলা যোগ করতে। এই থ্রেড বেলো পরীক্ষা করুন

https://github.com/googleapis/google-api-nodejs-client/issues/375

মুছে ফেলা অপারেটরের ব্যবহারের ভি 8 লুকানো শ্রেণির ধাঁচের জন্য পারফরম্যান্স নেতিবাচক প্রভাব রয়েছে। সাধারণত এটি ব্যবহার করবেন না এটি প্রস্তাবিত।

বিকল্পভাবে, অবজেক্টের নিজস্ব অগণিত বৈশিষ্ট্যগুলি সরিয়ে ফেলতে, আমরা সেই বৈশিষ্ট্যগুলি ছাড়াই একটি নতুন অবজেক্ট কপি তৈরি করতে পারি (উদাহরণস্বরূপ লোডাশ ব্যবহার করে):

_.মিট (ও, 'প্রপ', 'প্রোপ ২')

অথবা সম্পত্তি মানটি নাল বা অপরিজ্ঞাত হিসাবে সংজ্ঞায়িত করুন (যা জেএসএন-তে সিরিয়ালাইজ করার সময় স্পষ্টভাবে উপেক্ষা করা হয়):

o.prop = অপরিবর্তিত

আপনি খুব ধ্বংসাত্মক উপায় ব্যবহার করতে পারেন

const {remov1, remov2, ...new} = old;
old = new;

এবং আরও বাস্তব উদাহরণ:

this._volumes[this._minCandle] = undefined;
{ 
     const {[this._minCandle]: remove, ...rest} = this._volumes;
     this._volumes = rest; 
}

আপনি দেখতে পাচ্ছেন যে আপনি [somePropsVarForDynamicName]: scopeVarNameগতিশীল নামের জন্য সিনট্যাক্স ব্যবহার করতে পারেন । এবং আপনি সমস্ত ব্র্যাকেটগুলিতে রাখতে পারেন (নতুন ব্লক) যাতে বাকিগুলি আবর্জনার পরে সংগ্রহ করা হবে।

এখানে একটি পরীক্ষা: এখানে চিত্র বর্ণনা লিখুন

এক্সিকিউট:

এখানে চিত্র বর্ণনা লিখুন

অথবা আমরা যেমন কিছু ফাংশন সঙ্গে যেতে পারেন

function deleteProps(obj, props) {
    if (!Array.isArray(props)) props = [props];
    return Object.keys(obj).reduce((newObj, prop) => {
        if (!props.includes(prop)) {
            newObj[prop] = obj[prop];
        }
        return newObj;
    }, {});
}

প্রকারলিপি জন্য

function deleteProps(obj: Object, props: string[]) {
    if (!Array.isArray(props)) props = [props];
    return Object.keys(obj).reduce((newObj, prop) => {
        if (!props.includes(prop)) {
            newObj[prop] = obj[prop];
        }
        return newObj;
    }, {});
}

ব্যবহার:

let a = {propH: 'hi', propB: 'bye', propO: 'ok'};

a = deleteProps(a, 'propB'); 

// or 

a = deleteProps(a, ['propB', 'propO']);

এইভাবে একটি নতুন অবজেক্ট তৈরি করা হয়। এবং অবজেক্টের দ্রুত সম্পত্তি রাখা হয়। যা গুরুত্বপূর্ণ বা বিষয় হতে পারে। যদি ম্যাপিং এবং অবজেক্টটি বহুবার অ্যাক্সেস করা হবে।

এছাড়াও মেলামেশা undefinedকরা ভালভাবে চলতে পারে। যখন আপনি এটি সামর্থ্য করতে পারেন। এবং কীগুলির জন্য আপনি মানটিও পরীক্ষা করতে পারেন। উদাহরণস্বরূপ, সমস্ত সক্রিয় কীগুলি পেতে আপনি যেমন কিছু করেন:

const allActiveKeys = Object.keys(myObj).filter(k => myObj[k] !== undefined);
//or
const allActiveKeys = Object.keys(myObj).filter(k => myObj[k]); // if any false evaluated value is to be stripped.

অপরিজ্ঞাত বড় তালিকার জন্য উপযুক্ত না যদিও। বা সময়ের সাথে সাথে অনেকগুলি প্রপস আসবে বিকাশ As মেমরির ব্যবহারটি বাড়তে থাকবে এবং কখনই পরিষ্কার হবে না। সুতরাং এটি ব্যবহারের উপর নির্ভর করে। এবং কেবল একটি নতুন অবজেক্ট তৈরি করা ভাল উপায় বলে মনে হচ্ছে।

তারপরে Premature optimization is the root of all evilইচ্ছামত প্রবেশ করবে So সুতরাং আপনার ব্যবসায়ের বিষয়ে সচেতন হওয়া দরকার। এবং কি প্রয়োজন এবং কি না।

লোডাশ থেকে _.omit () সম্পর্কে নোট করুন

এটি সংস্করণ 5 থেকে সরানো হয়েছে আপনি রেপোতে এটি খুঁজে পাচ্ছেন না। এবং এখানে একটি বিষয় যা এটি সম্পর্কে কথা।

https://github.com/lodash/lodash/issues/2930

ভি 8

আপনি এটি দেখতে পারেন যা ভাল পঠনযোগ্য https://v8.dev/blog/fast-properties


1

কোনও ইএসলিন্ট রুল স্ট্যান্ডার্ড থেকে স্বীকৃত উত্তরের সাথে আমার ইস্যু, যদি আপনি বিকৃত করার চেষ্টা করেন:

    const { notNeeded, alsoNotNeeded, ...rest } = { ...ogObject };

2 টি নতুন ভেরিয়েবল notNeededএবং alsoNotNeededআপনার সেটআপের উপর নির্ভর করে কোনও সতর্কতা বা ত্রুটি ফেলে দিতে পারে যেহেতু সেগুলি এখন অব্যবহৃত। তাহলে অব্যবহৃত হলে কেন নতুন ভার্স তৈরি করবেন?

আমি মনে করি আপনার deleteসঠিকভাবে ফাংশনটি ব্যবহার করা উচিত ।


4
no-unused-varsনিয়ম আসলে একটি বিকল্প থাকে ignoreRestSiblings: এই ব্যবহারের ক্ষেত্রে আবরণ এখন eslint.org/docs/rules/no-unused-vars#ignorerestsiblings
amann

0

লোডাস ক্লোনডিপ সহ মুছে দিন

(দ্রষ্টব্য: অগভীর বস্তুর পরিবর্তে লোডাশ ক্লোন ব্যবহার করা যেতে পারে)

const obj = {a: 1, b: 2, c: 3}
const unwantedKey = 'a'

const _ = require('lodash')
const objCopy = _.cloneDeep(obj)
delete objCopy[unwantedKey]
// objCopy = {b: 2, c: 3}

0

আমার কোডের জন্য আমি মানচিত্রের ফেরতের মানটির সংক্ষিপ্ত সংস্করণ চেয়েছিলাম () তবে মাল্টলাইন / মুটলি অপারেশন সমাধানগুলি ছিল "কুশ্রী"। মূল বৈশিষ্ট্যটি পুরানো void(0)যা সমাধান করা হয় undefinedresolve

let o2 = {...o, age: 31, lastname: void(0)};

সম্পত্তি অবজেক্টে থাকে:

console.log(o2) // {firstname: "Jane", lastname: undefined, age: 31}

তবে সংক্রমণ ফ্রেমওয়ার্কটি এটি আমার জন্য মেরে ফেলে (বিসি স্ট্রিংফাই):

console.log(JSON.stringify(o2)) // {"firstname":"Jane","age":31}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.