জাভাস্ক্রিপ্টে বুলিয়ান শর্তের সাথে মেলানো অ্যারের প্রথম উপাদানটি কীভাবে খুঁজে পাবেন?


219

আমি ভাবছি যে প্রদত্ত শর্তের সাথে মিলে জেএস অ্যারের প্রথম উপাদানটি খুঁজে পেতে কোনও ज्ञিত, ​​অন্তর্নির্মিত / মার্জিত উপায় আছে কিনা। এসি # সমতুল্য তালিকা.ফাইন্ড হবে

এখনও অবধি আমি এর মতো একটি দ্বি-ফাংশন কম্বো ব্যবহার করছি:

// Returns the first element of an array that satisfies given predicate
Array.prototype.findFirst = function (predicateCallback) {
    if (typeof predicateCallback !== 'function') {
        return undefined;
    }

    for (var i = 0; i < arr.length; i++) {
        if (i in this && predicateCallback(this[i])) return this[i];
    }

    return undefined;
};

// Check if element is not undefined && not null
isNotNullNorUndefined = function (o) {
    return (typeof (o) !== 'undefined' && o !== null);
};

এবং তারপরে আমি এটি ব্যবহার করতে পারি:

var result = someArray.findFirst(isNotNullNorUndefined);

তবে যেহেতু ECMAScript এ অনেকগুলি কার্যকরী-শৈলীর অ্যারে পদ্ধতি রয়েছে , সম্ভবত ইতিমধ্যে এর মতো কিছু আছে? আমি কল্পনা করি প্রচুর লোককে সর্বদা এভাবে স্টাফ প্রয়োগ করতে হয় ...


6
পদ্ধতিতে কোনও অন্তর্নির্মিত নেই, তবে এমন ইউটিলিটি লাইব্রেরি রয়েছে যা এই কার্যকারিতাটি আনুমানিকভাবে ডকুমেন্টক্লাউড.
github.com/underscore

অ্যান্ডসোর.জেএস দেখতে খুব সুন্দর লাগছে! এবং এটি খুঁজে পেয়েছে ()। ধন্যবাদ!
জাকুব পি।

1
ঠিক তাই আপনি জানেন, আপনি এটি হ্রাস করতে পারেন: return (typeof (o) !== 'undefined' && o !== null);এটি এখানে return o != null;। তারা ঠিক সমতুল্য।
পাগলামি ক্লিফস

1
জানা ভাল. তবে আপনি জানেন, আমি জোর দেওয়া অপারেটরগুলিকে অবিশ্বাস করি! = বা ==। এমনকি আমি এটি সহজেই পরীক্ষা করতে সক্ষম হব না, কারণ আমার কোনওভাবে পরীক্ষা করা দরকার যে ফ্যাশনটি বাতিল করতে বাধ্য করা হয় এমন অন্য কোনও মূল্য নেই ... :) সুতরাং আমি যে লাইব্রেরির অনুমতি পেয়েছি তা পেয়ে আমি কত ভাগ্যবান! আমাকে পুরোপুরি এই ফাংশনটি সরিয়ে ফেলতে হবে ... :)
জাকব পি।

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

উত্তর:


218

ES6 যেহেতু অ্যারেগুলির জন্য স্থানীয় findপদ্ধতি রয়েছে ; এটি যখন প্রথম ম্যাচটি খুঁজে বের করে এবং মানটি দেয় তখন এটি অ্যারের গণনা বন্ধ করে দেয়।

const result = someArray.find(isNotNullNorUndefined);

পুরানো উত্তর:

এই filterপরামর্শগুলি বন্ধ করতে আমাকে একটি উত্তর পোস্ট করতে হবে :-)

যেহেতু ECMAScript এ অনেকগুলি কার্যকরী-শৈলীর অ্যারে পদ্ধতি রয়েছে, সম্ভবত ইতিমধ্যে এর মতো কিছু আছে?

শর্ত পূরণ না হওয়া অবধি অ্যারে পুনরুক্ত করার জন্য আপনি someঅ্যারে পদ্ধতিটি ব্যবহার করতে পারেন (এবং তারপরে থামুন)। দুর্ভাগ্যক্রমে এটি কেবল শর্তটি একবার পূরণ হয়েছিল কিনা তা ফিরে আসবে, কোন উপাদান দ্বারা (বা কোন সূচকে) এটি পূরণ হয়েছিল তা নয়। সুতরাং আমাদের এটি একটু সংশোধন করতে হবে:

function find(arr, test, ctx) {
    var result = null;
    arr.some(function(el, i) {
        return test.call(ctx, el, i, arr) ? ((result = el), true) : false;
    });
    return result;
}

var result = find(someArray, isNotNullNorUndefined);

28
বলতে পারি না আমি ফিল্টার () এ নির্দেশিত সমস্ত অপছন্দ সম্পূর্ণরূপে বুঝতে পারি। এটি ধীর হতে পারে তবে বাস্তবে; বেশিরভাগ ক্ষেত্রে যেখানে এটি সম্ভবত ব্যবহৃত হয়, এটি শুরু করার জন্য এটি একটি ছোট তালিকা এবং জাভাস্ক্রিপ্টের বেশিরভাগ অ্যাপ্লিকেশনগুলি এই স্তরের দক্ষতা সম্পর্কে সত্যই চিন্তিত হওয়ার পক্ষে যথেষ্ট জটিল নয়। [] .ফিল্টার (পরীক্ষা) .পপ () বা []। ফিল্টার (পরীক্ষা) [0] সহজ, নেটিভ এবং পঠনযোগ্য। অবশ্যই আমি ব্যবসায়িক অ্যাপস বা গেমসের মতো নিবিড় অ্যাপ্লিকেশন নয় এমন ওয়েবসাইটগুলির বিষয়ে বলছি।
জোশ ম্যাক

11
ফিল্টার সমাধানগুলি সমস্ত অ্যারে / সংগ্রহকে অতিক্রম করে? যদি তা হয় তবে ফিল্টারিংটি খুব অদক্ষ, কারণ এটি সংগ্রহস্থলের মধ্যে পাওয়া মানটি হলেও এটি সমস্ত অ্যারের উপরে চলে over some()অন্যদিকে, অবিলম্বে ফিরে আসে, যা ফিল্টারিং সমাধানগুলির চেয়ে প্রায় সব ক্ষেত্রেই অনেক দ্রুত।
অ্যালিকেলজিন-কিলাকা

@ অ্যালিকেলজিন-কিলাকা: হ্যাঁ, ঠিক
বার্গি

15
@ জোশ এমসি নিশ্চিত, তবে স্ট্যাক ওভারফ্লোয়ের মতো কোথাও কোনও সাধারণ সমস্যার সমাধান পোস্ট করার সময় কৃতজ্ঞতাহীনভাবে অদক্ষ না হওয়ার বিষয়টি বোঝায়। প্রচুর লোক এখান থেকে কোডটি অনুলিপি করে একটি ইউটিলিটি ফাংশনে আটকান এবং তাদের মধ্যে কেউ কেউ কোনও এক সময় সেই ইউটিলিটি ফাংশনটি ব্যবহার করে শেষ করবে যেখানে কার্যকারিতা বাস্তবায়নের বিষয়ে চিন্তা না করেই গুরুত্বপূর্ণ। আপনি যদি তাদের এমন কিছু দিয়েছিলেন যার সাথে শুরু করার একটি দক্ষ বাস্তবায়ন রয়েছে, তবে আপনি তাদের কার্য সম্পাদন সমস্যাটি সমাধান করেছেন যা অন্যথায় না হয়, বা এটি নির্ণয় করার জন্য তাদের বেশ কিছু সময় সাশ্রয় করেছেন।
মার্ক অ্যামেরি

1
@ সুপারউবারডুপার: না। নীচে মার্ক অ্যামেরির উত্তর দেখুন।
বার্গি

104

ECMAScript 6 হিসাবে, আপনি এটির Array.prototype.findজন্য ব্যবহার করতে পারেন । এটি প্রয়োগ করা হয়েছে এবং ফায়ারফক্স (25.0), ক্রোম (45.0), এজ (12), এবং সাফারি (7.1) তে কাজ করা হয়েছে, তবে ইন্টারনেট এক্সপ্লোরার বা অন্যান্য পুরানো বা অস্বাভাবিক প্ল্যাটফর্মগুলিতে নয়

উদাহরণস্বরূপ, নীচের অভিব্যক্তিটি মূল্যায়ন করে 106

[100,101,102,103,104,105,106,107,108,109].find(function (el) {
    return el > 105;
});

আপনি যদি এখনই এটি ব্যবহার করতে চান তবে IE বা অন্যান্য অসমর্থিত ব্রাউজারগুলির জন্য সমর্থন প্রয়োজন, আপনি একটি শিম ব্যবহার করতে পারেন। আমি es6-shim সুপারিশ । যদি কোনও কারণে আপনি আপনার প্রকল্পে পুরো এস-শিমটি রাখতে চান না তবে এমডিএন একটি শিমও দেয়। সর্বাধিক সামঞ্জস্যের জন্য আপনি এস 6-শিমটি চান, কারণ এমডিএন সংস্করণের বিপরীতে এটি বগি নেটিভ বাস্তবায়ন সনাক্ত করে findএবং সেগুলি ওভাররাইট করে (মন্তব্যটি দেখুন যা "অ্যারেতে # বাগের চারপাশে কাজ শুরু করে # অ্যারে # ফাইন্ড ইন্ডেক্স" এবং তত্ক্ষণাত লাইনগুলি দেখুন) ।


findfilterযেহেতু findশর্তের সাথে কোনও উপাদান মিলে একটি উপাদান পাওয়া যায় তত্ক্ষণাত্ থেমে যাওয়ার চেয়ে ভাল , যখন filterসমস্ত মিলিত উপাদান দেওয়ার জন্য সমস্ত উপাদানকে লুপ করে।
আনহ ট্রান

59

ফিল্টার ব্যবহার এবং ফলাফল অ্যারে থেকে প্রথম সূচক পাওয়ার সম্পর্কে কী ?

var result = someArray.filter(isNotNullNorUndefined)[0];

6
এস 5 পদ্ধতি ব্যবহার করা চালিয়ে যান। var ফলাফল = someArray.filter (isNotNullNorUndefined)। শিফট ();
someyoungideas

যদিও আমি নিজে @ বার্গির উপরে উত্তর খুঁজে পেতে ভোট দিয়েছি, তবে আমি মনে করি ES6 ধ্বংসের মাধ্যমে আমরা কিছুটা উপরে উন্নতি করতে পারি: var [ফলাফল] = কিছুআর্রে.ফিল্টার (isNotNullNorUndefined);
নকুল মনছন্দ

আপনি কি .shiftএখানে কিছু ব্যবহারের সুবিধাটি ব্যাখ্যা করতে পারেন ?
jakubiszon

3
@ জাকুবিসজন ব্যবহারের সুবিধাটি shiftহ'ল এটি "স্মার্ট" দেখায় তবে এটি আরও বিভ্রান্তিকর। কে ভাববে যে shift()কোনও যুক্তি দিয়ে কল করা প্রথম উপাদানটি গ্রহণের সমান হবে? এটি অস্পষ্ট আইএমও। অ্যারে অ্যাক্সেস যাহাই হউক না কেন দ্রুত হয়: jsperf.com/array-access-vs-shift
জোশ এম।

এছাড়াও, ES5 AFAIK এ দুটি বস্তু এবং অ্যারে উভয়ের জন্য স্কোয়ার ব্র্যাকেট স্বরলিপি পাওয়া যায়, এর .shift()আগে [0]স্পষ্টভাবে বর্ণিত ওভারের পছন্দ কখনও দেখেনি । তা সত্ত্বেও, এটি এমন একটি বিকল্প যা আপনি বেছে নিতে পারেন বা ব্যবহার করতে পারেন, আমি [0]যদিও এর সাথে থাকি ।
সিডোএফসি

15

এটি এখনই স্পষ্ট হওয়া উচিত যে জাভাস্ক্রিপ্ট স্থানীয়ভাবে এর কোনও সমাধান দেয় না; এখানে নিকটতম দুটি ডেরিভেটিভ রয়েছে, সবচেয়ে কার্যকর প্রথম:

  1. Array.prototype.some(fn)কোনও শর্ত পূরণ হলে থামার কাঙ্ক্ষিত আচরণের প্রস্তাব দেয় তবে কেবল কোনও উপাদান উপস্থিত রয়েছে কিনা তা ফেরত দেয়; কিছু ছলচাতুরী প্রয়োগ করা শক্ত নয়, যেমন বার্গির উত্তর দিয়ে দেওয়া সমাধান ।

  2. Array.prototype.filter(fn)[0]একটি দুর্দান্ত এক-লাইনারের জন্য তৈরি করে তবে এটি সবচেয়ে কম দক্ষ, কারণ N - 1আপনি যা প্রয়োজন তা পেতে আপনি উপাদানগুলি ফেলে দেন ।

জাভাস্ক্রিপ্টে ditionতিহ্যবাহী অনুসন্ধানের পদ্ধতিগুলি এলিমেন্টের পরিবর্তে বা -1 এর পরিবর্তে পাওয়া উপাদানটির সূচি ফিরিয়ে চিহ্নিত করা হয়। এটি সমস্ত সম্ভাব্য প্রকারের ডোমেন থেকে কোনও রিটার্ন মান নির্বাচন করা এড়ায়; একটি সূচক কেবল একটি সংখ্যা হতে পারে এবং নেতিবাচক মানগুলি অবৈধ।

উপরের উভয় সমাধানই অফসেট অনুসন্ধানকে সমর্থন করে না, তাই আমি এটি লেখার সিদ্ধান্ত নিয়েছি:

(function(ns) {
  ns.search = function(array, callback, offset) {
    var size = array.length;

    offset = offset || 0;
    if (offset >= size || offset <= -size) {
      return -1;
    } else if (offset < 0) {
      offset = size - offset;
    }

    while (offset < size) {
      if (callback(array[offset], offset, array)) {
        return offset;
      }
      ++offset;
    }
    return -1;
  };
}(this));

search([1, 2, NaN, 4], Number.isNaN); // 2
search([1, 2, 3, 4], Number.isNaN); // -1
search([1, NaN, 3, NaN], Number.isNaN, 2); // 3

সর্বাধিক বিস্তৃত উত্তর বলে মনে হচ্ছে। আপনি কি আপনার উত্তরে তৃতীয় পন্থা যুক্ত করতে পারেন?
মিউজফুল

13

সারসংক্ষেপ:

  • অ্যারেতে প্রথম উপাদানটি আবিষ্কার করার জন্য যা আমরা ব্যবহার করতে পারি সেই বুলিয়ান শর্তের সাথে মেলে ES6 find()
  • find()এটি অবস্থিত Array.prototypeতাই এটি প্রতিটি অ্যারে ব্যবহার করা যেতে পারে।
  • find()একটি কলব্যাক নেয় যেখানে একটি booleanশর্ত পরীক্ষা করা হয়। ফাংশনটি মান দেয় (সূচি নয়!)

উদাহরণ:

const array = [4, 33, 8, 56, 23];

const found = array.find((element) => {
  return element > 50;
});

console.log(found);   //  56


8

আপনি যদি ব্যবহার করেন তবে underscore.jsআপনি যা চান ঠিক তা পেতে এর findএবং indexOfফাংশনগুলি ব্যবহার করতে পারেন:

var index = _.indexOf(your_array, _.find(your_array, function (d) {
    return d === true;
}));

ডকুমেন্টেশন:


প্রয়োজন হলে আন্ডারস্কোর বিকল্পটি ব্যবহার করুন কারণ এটির জন্য একটি লাইব্রেরি লোড করুন কেবল এটির মূল্য নয়
ড্যানিফেলিজ

4

ES 2015 হিসাবে, Array.prototype.find()এই সঠিক কার্যকারিতা সরবরাহ করে।

এই বৈশিষ্ট্যটি সমর্থন করে না এমন ব্রাউজারগুলির জন্য, মজিলা বিকাশকারী নেটওয়ার্ক একটি পলিফিল সরবরাহ করেছে (নীচে আটকানো):

if (!Array.prototype.find) {
  Array.prototype.find = function(predicate) {
    if (this === null) {
      throw new TypeError('Array.prototype.find called on null or undefined');
    }
    if (typeof predicate !== 'function') {
      throw new TypeError('predicate must be a function');
    }
    var list = Object(this);
    var length = list.length >>> 0;
    var thisArg = arguments[1];
    var value;

    for (var i = 0; i < length; i++) {
      value = list[i];
      if (predicate.call(thisArg, value, i, list)) {
        return value;
      }
    }
    return undefined;
  };
}


2
foundElement = myArray[myArray.findIndex(element => //condition here)];

3
শর্তের ধারা এবং কিছু ব্যাখ্যামূলক শব্দ সহ একটি বাস্তব জীবনের উদাহরণ আপনার উত্তরটিকে আরও মূল্যবান এবং বোধগম্য করে তুলবে।
SaschaM78

0

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

ব্যবহার: ("দ্বিতীয়" মান প্রদান)

var defaultItemValue = { id: -1, name: "Undefined" };
var containers: Container[] = [{ id: 1, name: "First" }, { id: 2, name: "Second" }];
GetContainer(2).name;

বাস্তবায়ন:

class Container {
    id: number;
    name: string;
}

public GetContainer(containerId: number): Container {
  var comparator = (item: Container): boolean => {
      return item.id == containerId;
    };
    return this.Get<Container>(this.containers, comparator, this.defaultItemValue);
  }

private Get<T>(array: T[], comparator: (item: T) => boolean, defaultValue: T): T {
  var found: T = null;
  array.some(function(element, index) {
    if (comparator(element)) {
      found = element;
      return true;
    }
  });

  if (!found) {
    found = defaultValue;
  }

  return found;
}

-2

এই অনুসন্ধানটি সম্পাদনের জন্য জাভাস্ক্রিপ্টে কোনও অন্তর্নির্মিত ফাংশন নেই।

আপনি jQuery ব্যবহার করা হয় আপনি একটি করতে পারেন jQuery.inArray(element,array)


এটি খুব কার্যকর হবে, যদিও আমি সম্ভবত অ্যান্ডস্কোরের সাথে যাব :)
জাকুব পি।

3
এটি প্রশ্নকর্তা যা প্রয়োজন তার আউটপুট সন্তুষ্ট করে না (কোনও সূচকের উপাদানটির প্রয়োজন, বুলিয়ান নয়)।
গ্রাহাম রবার্টসন

@ গ্রাহামরোবার্টসন $.inArrayকোনও বুলিয়ান ফিরিয়ে দেয় না, এটি (আশ্চর্যজনকভাবে) প্রথম মিলের উপাদানটির সূচক ফেরত দেয়। যদিও এটি ওপি যা চেয়েছিল তা এখনও করে না।
মার্ক আমেরিকা

-2

একটি কম মার্জিত উপায় যা throwসমস্ত সঠিক ত্রুটি বার্তাগুলি (উপর ভিত্তি করে Array.prototype.filter) করবে কিন্তু প্রথম ফলাফলটিতে পুনরাবৃত্তি বন্ধ করবে is

function findFirst(arr, test, context) {
    var Result = function (v, i) {this.value = v; this.index = i;};
    try {
        Array.prototype.filter.call(arr, function (v, i, a) {
            if (test(v, i, a)) throw new Result(v, i);
        }, context);
    } catch (e) {
        if (e instanceof Result) return e;
        throw e;
    }
}

তারপরে উদাহরণগুলি হ'ল

findFirst([-2, -1, 0, 1, 2, 3], function (e) {return e > 1 && e % 2;});
// Result {value: 3, index: 5}
findFirst([0, 1, 2, 3], 0);               // bad function param
// TypeError: number is not a function
findFirst(0, function () {return true;}); // bad arr param
// undefined
findFirst([1], function (e) {return 0;}); // no match
// undefined

এটি filterব্যবহার করে শেষ করে কাজ করে throw

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.